001: /*
002: * SSHTools - Java SSH2 API
003: *
004: * Copyright (C) 2002-2003 Lee David Painter and Contributors.
005: *
006: * Contributions made by:
007: *
008: * Brett Smith
009: * Richard Pernavas
010: * Erwin Bolwidt
011: *
012: * This program is free software; you can redistribute it and/or
013: * modify it under the terms of the GNU General Public License
014: * as published by the Free Software Foundation; either version 2
015: * of the License, or (at your option) any later version.
016: *
017: * This program is distributed in the hope that it will be useful,
018: * but WITHOUT ANY WARRANTY; without even the implied warranty of
019: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
020: * GNU General Public License for more details.
021: *
022: * You should have received a copy of the GNU General Public License
023: * along with this program; if not, write to the Free Software
024: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
025: */
026: package com.sshtools.common.configuration;
027:
028: import com.sshtools.j2ssh.configuration.*;
029:
030: import org.xml.sax.*;
031: import org.xml.sax.helpers.*;
032:
033: import java.io.*;
034:
035: import java.util.*;
036:
037: import javax.xml.parsers.*;
038:
039: /**
040: *
041: *
042: * @author $author$
043: * @version $Revision: 1.12 $
044: */
045: public class SshAPIConfiguration extends DefaultHandler implements
046: com.sshtools.j2ssh.configuration.SshAPIConfiguration {
047: private String defaultCipher = null;
048: private String defaultMac = null;
049: private String defaultCompression = null;
050: private String defaultPublicKey = null;
051: private String defaultKeyExchange = null;
052: private List cipherExtensions = new ArrayList();
053: private List macExtensions = new ArrayList();
054: private List compressionExtensions = new ArrayList();
055: private List pkExtensions = new ArrayList();
056: private List kexExtensions = new ArrayList();
057: private List authExtensions = new ArrayList();
058: private List pkFormats = new ArrayList();
059: private List prvFormats = new ArrayList();
060: private String defaultPublicFormat = null;
061: private String defaultPrivateFormat = null;
062: private String currentElement = null;
063: private String parentElement = null;
064: private List currentList = null;
065: private ExtensionAlgorithm currentExt = null;
066:
067: /**
068: * Creates a new SshAPIConfiguration object.
069: *
070: * @param in
071: *
072: * @throws SAXException
073: * @throws ParserConfigurationException
074: * @throws IOException
075: */
076: public SshAPIConfiguration(InputStream in) throws SAXException,
077: ParserConfigurationException, IOException {
078: reload(in);
079: }
080:
081: /**
082: *
083: *
084: * @param in
085: *
086: * @throws SAXException
087: * @throws ParserConfigurationException
088: * @throws IOException
089: */
090: public void reload(InputStream in) throws SAXException,
091: ParserConfigurationException, IOException {
092: defaultCipher = null;
093: defaultMac = null;
094: defaultCompression = null;
095: defaultKeyExchange = null;
096: defaultPublicKey = null;
097: defaultPublicFormat = null;
098: defaultPrivateFormat = null;
099: cipherExtensions.clear();
100: macExtensions.clear();
101: compressionExtensions.clear();
102: pkExtensions.clear();
103: kexExtensions.clear();
104: authExtensions.clear();
105: pkFormats.clear();
106: prvFormats.clear();
107:
108: SAXParserFactory saxFactory = SAXParserFactory.newInstance();
109: SAXParser saxParser = saxFactory.newSAXParser();
110: saxParser.parse(in, this );
111: }
112:
113: /**
114: *
115: *
116: * @param ch
117: * @param start
118: * @param length
119: *
120: * @throws SAXException
121: */
122: public void characters(char[] ch, int start, int length)
123: throws SAXException {
124: String value = new String(ch, start, length);
125:
126: if (currentElement != null) {
127: if (currentElement.equals("AlgorithmName")) {
128: if (currentExt != null) {
129: currentExt.setAlgorithmName(value);
130: } else {
131: throw new SAXException(
132: "Unexpected AlgorithmName element!");
133: }
134:
135: return;
136: }
137:
138: if (currentElement.equals("ImplementationClass")) {
139: if (currentExt != null) {
140: currentExt.setImplementationClass(value);
141: } else {
142: throw new SAXException(
143: "Unexpected ImplementationClass element!");
144: }
145:
146: return;
147: }
148:
149: if (currentElement.equals("DefaultAlgorithm")) {
150: if (parentElement.equals("CipherConfiguration")) {
151: defaultCipher = value;
152: } else if (parentElement.equals("MacConfiguration")) {
153: defaultMac = value;
154: } else if (parentElement
155: .equals("CompressionConfiguration")) {
156: defaultCompression = value;
157: } else if (parentElement
158: .equals("PublicKeyConfiguration")) {
159: defaultPublicKey = value;
160: } else if (parentElement
161: .equals("KeyExchangeConfiguration")) {
162: defaultKeyExchange = value;
163: } else {
164: throw new SAXException(
165: "Unexpected parent elemenet for DefaultAlgorithm element");
166: }
167: }
168:
169: if (currentElement.equals("DefaultPublicFormat")) {
170: defaultPublicFormat = value;
171: }
172:
173: if (currentElement.equals("DefaultPrivateFormat")) {
174: defaultPrivateFormat = value;
175: }
176: }
177: }
178:
179: /**
180: *
181: *
182: * @param uri
183: * @param localName
184: * @param qname
185: *
186: * @throws SAXException
187: */
188: public void endElement(String uri, String localName, String qname)
189: throws SAXException {
190: if (currentElement != null) {
191: if (!currentElement.equals(qname)) {
192: throw new SAXException("Unexpected end element found "
193: + qname);
194: } else if (currentElement.equals("SshAPIConfiguration")) {
195: currentElement = null;
196: } else if (currentElement.equals("CipherConfiguration")
197: || currentElement.equals("MacConfiguration")
198: || currentElement.equals("PublicKeyConfiguration")
199: || currentElement
200: .equals("CompressionConfiguration")
201: || currentElement
202: .equals("KeyExchangeConfiguration")
203: || currentElement
204: .equals("AuthenticationConfiguration")) {
205: currentList = null;
206: currentElement = "SshAPIConfiguration";
207: } else if (currentElement.equals("ExtensionAlgorithm")) {
208: if (currentExt == null) {
209: throw new SAXException(
210: "Critical error, null extension algortihm");
211: }
212:
213: if ((currentExt.getAlgorithmName() == null)
214: || (currentExt.getImplementationClass() == null)) {
215: throw new SAXException(
216: "Unexpected end of ExtensionAlgorithm Element");
217: }
218:
219: currentList.add(currentExt);
220: currentExt = null;
221: currentElement = parentElement;
222: } else if (currentElement.equals("DefaultAlgorithm")
223: || currentElement.equals("DefaultPublicFormat")
224: || currentElement.equals("DefaultPrivateFormat")
225: || currentElement.equals("PublicKeyFormat")
226: || currentElement.equals("PrivateKeyFormat")) {
227: currentElement = parentElement;
228: } else if (currentElement.equals("AlgorithmName")) {
229: currentElement = "ExtensionAlgorithm";
230: } else if (currentElement.equals("ImplementationClass")) {
231: currentElement = "ExtensionAlgorithm";
232: } else {
233: throw new SAXException("Unexpected end element "
234: + qname);
235: }
236: }
237: }
238:
239: /**
240: *
241: *
242: * @param uri
243: * @param localName
244: * @param qname
245: * @param attrs
246: *
247: * @throws SAXException
248: */
249: public void startElement(String uri, String localName,
250: String qname, Attributes attrs) throws SAXException {
251: if (currentElement == null) {
252: if (!qname.equals("SshAPIConfiguration")) {
253: throw new SAXException("Unexpected root element "
254: + qname);
255: }
256: } else {
257: if (currentElement.equals("SshAPIConfiguration")) {
258: if (!qname.equals("CipherConfiguration")
259: && !qname.equals("MacConfiguration")
260: && !qname.equals("CompressionConfiguration")
261: && !qname.equals("PublicKeyConfiguration")
262: && !qname.equals("AuthenticationConfiguration")
263: && !qname.equals("KeyExchangeConfiguration")) {
264: throw new SAXException("Unexpected <" + qname
265: + "> element after SshAPIConfiguration");
266: }
267: } else if (currentElement.equals("CipherConfiguration")) {
268: if (qname.equals("ExtensionAlgorithm")) {
269: currentList = cipherExtensions;
270: parentElement = currentElement;
271: currentExt = new ExtensionAlgorithm();
272: } else if (qname.equals("DefaultAlgorithm")) {
273: parentElement = currentElement;
274: } else {
275: throw new SAXException("Unexpected element <"
276: + qname
277: + "> found after CipherConfiguration");
278: }
279: } else if (currentElement.equals("MacConfiguration")) {
280: if (qname.equals("ExtensionAlgorithm")) {
281: currentList = macExtensions;
282: parentElement = currentElement;
283: currentExt = new ExtensionAlgorithm();
284: } else if (qname.equals("DefaultAlgorithm")) {
285: parentElement = currentElement;
286: } else {
287: throw new SAXException("Unexpected element <"
288: + qname
289: + "> found after CipherConfiguration");
290: }
291: } else if (currentElement
292: .equals("CompressionConfiguration")) {
293: if (qname.equals("ExtensionAlgorithm")) {
294: currentList = compressionExtensions;
295: parentElement = currentElement;
296: currentExt = new ExtensionAlgorithm();
297: } else if (qname.equals("DefaultAlgorithm")) {
298: parentElement = currentElement;
299: } else {
300: throw new SAXException("Unexpected element <"
301: + qname
302: + "> found after CompressionConfiguration");
303: }
304: } else if (currentElement.equals("PublicKeyConfiguration")) {
305: if (qname.equals("ExtensionAlgorithm")) {
306: currentList = pkExtensions;
307: parentElement = currentElement;
308: currentExt = new ExtensionAlgorithm();
309: } else if (qname.equals("DefaultAlgorithm")) {
310: parentElement = currentElement;
311: } else if (qname.equals("PublicKeyFormat")) {
312: String cls = attrs.getValue("ImplementationClass");
313:
314: if (cls == null) {
315: throw new SAXException(
316: "<PublicKeyFormat> element requries the ImplementationClass attribute");
317: }
318:
319: pkFormats.add(cls);
320: } else if (qname.equals("PrivateKeyFormat")) {
321: String cls = attrs.getValue("ImplementationClass");
322:
323: if (cls == null) {
324: throw new SAXException(
325: "<PrivateKeyFormat> element requries the ImplementationClass attribute");
326: }
327:
328: prvFormats.add(cls);
329: } else if (qname.equals("DefaultPublicFormat")) {
330: parentElement = currentElement;
331: } else if (qname.equals("DefaultPrivateFormat")) {
332: parentElement = currentElement;
333: } else {
334: throw new SAXException("Unexpected element <"
335: + qname
336: + "> found after PublicKeyConfiguration");
337: }
338: } else if (currentElement
339: .equals("AuthenticationConfiguration")) {
340: if (qname.equals("ExtensionAlgorithm")) {
341: currentList = authExtensions;
342: parentElement = currentElement;
343: currentExt = new ExtensionAlgorithm();
344: } else {
345: throw new SAXException(
346: "Unexpected element <"
347: + qname
348: + "> found after AuthenticationConfiguration");
349: }
350: } else if (currentElement
351: .equals("KeyExchangeConfiguration")) {
352: if (qname.equals("ExtensionAlgorithm")) {
353: currentList = kexExtensions;
354: parentElement = currentElement;
355: currentExt = new ExtensionAlgorithm();
356: } else if (qname.equals("DefaultAlgorithm")) {
357: parentElement = currentElement;
358: } else {
359: throw new SAXException("Unexpected element <"
360: + qname
361: + "> found after KeyExchangeConfiguration");
362: }
363: } else if ((currentElement.equals("ExtensionAlgorithm") && qname
364: .equals("AlgorithmName"))
365: || (currentElement.equals("ExtensionAlgorithm") && qname
366: .equals("ImplementationClass"))) {
367: } else {
368: throw new SAXException("Unexpected element " + qname);
369: }
370: }
371:
372: currentElement = qname;
373: }
374:
375: /**
376: *
377: *
378: * @return
379: */
380: public List getCompressionExtensions() {
381: return compressionExtensions;
382: }
383:
384: /**
385: *
386: *
387: * @return
388: */
389: public List getCipherExtensions() {
390: return cipherExtensions;
391: }
392:
393: /**
394: *
395: *
396: * @return
397: */
398: public List getMacExtensions() {
399: return macExtensions;
400: }
401:
402: /**
403: *
404: *
405: * @return
406: */
407: public List getAuthenticationExtensions() {
408: return authExtensions;
409: }
410:
411: /**
412: *
413: *
414: * @return
415: */
416: public List getPublicKeyExtensions() {
417: return pkExtensions;
418: }
419:
420: /**
421: *
422: *
423: * @return
424: */
425: public List getKeyExchangeExtensions() {
426: return kexExtensions;
427: }
428:
429: /**
430: *
431: *
432: * @return
433: */
434: public String getDefaultCipher() {
435: return defaultCipher;
436: }
437:
438: /**
439: *
440: *
441: * @return
442: */
443: public String getDefaultMac() {
444: return defaultMac;
445: }
446:
447: /**
448: *
449: *
450: * @return
451: */
452: public String getDefaultCompression() {
453: return defaultCompression;
454: }
455:
456: /**
457: *
458: *
459: * @return
460: */
461: public String getDefaultPublicKey() {
462: return defaultPublicKey;
463: }
464:
465: /**
466: *
467: *
468: * @return
469: */
470: public String getDefaultKeyExchange() {
471: return defaultKeyExchange;
472: }
473:
474: /**
475: *
476: *
477: * @return
478: */
479: public String getDefaultPublicKeyFormat() {
480: return defaultPublicFormat;
481: }
482:
483: /**
484: *
485: *
486: * @return
487: */
488: public String getDefaultPrivateKeyFormat() {
489: return defaultPrivateFormat;
490: }
491:
492: /**
493: *
494: *
495: * @return
496: */
497: public List getPublicKeyFormats() {
498: return pkFormats;
499: }
500:
501: /**
502: *
503: *
504: * @return
505: */
506: public List getPrivateKeyFormats() {
507: return prvFormats;
508: }
509:
510: /**
511: *
512: *
513: * @return
514: */
515: public String toString() {
516: String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
517: xml += "<!-- Sshtools J2SSH Configuration file -->\n";
518: xml += "<SshAPIConfiguration>\n";
519: xml += " <!-- The Cipher configuration, add or overide default cipher implementations -->\n";
520: xml += " <CipherConfiguration>\n";
521:
522: Iterator it = cipherExtensions.iterator();
523: ExtensionAlgorithm ext;
524:
525: while (it.hasNext()) {
526: ext = (ExtensionAlgorithm) it.next();
527: xml += " <ExtensionAlgorithm>\n";
528: xml += (" <AlgorithmName>" + ext.getAlgorithmName() + "</AlgorithmName>\n");
529: xml += (" <ImplementationClass>"
530: + ext.getImplementationClass() + "</ImplementationClass>\n");
531: xml += " </ExtensionAlgorithm>\n";
532: }
533:
534: xml += (" <DefaultAlgorithm>" + defaultCipher + "</DefaultAlgorithm>\n");
535: xml += " </CipherConfiguration>\n";
536: xml += " <!-- The Mac configuration, add or overide default mac implementations -->\n";
537: xml += " <MacConfiguration>\n";
538: it = macExtensions.iterator();
539:
540: while (it.hasNext()) {
541: ext = (ExtensionAlgorithm) it.next();
542: xml += " <ExtensionAlgorithm>\n";
543: xml += (" <AlgorithmName>" + ext.getAlgorithmName() + "</AlgorithmName>\n");
544: xml += (" <ImplementationClass>"
545: + ext.getImplementationClass() + "</ImplementationClass>\n");
546: xml += " </ExtensionAlgorithm>\n";
547: }
548:
549: xml += (" <DefaultAlgorithm>" + defaultMac + "</DefaultAlgorithm>\n");
550: xml += " </MacConfiguration>\n";
551: xml += " <!-- The Compression configuration, add or overide default compression implementations -->\n";
552: xml += " <CompressionConfiguration>\n";
553: it = compressionExtensions.iterator();
554:
555: while (it.hasNext()) {
556: ext = (ExtensionAlgorithm) it.next();
557: xml += " <ExtensionAlgorithm>\n";
558: xml += (" <AlgorithmName>" + ext.getAlgorithmName() + "</AlgorithmName>\n");
559: xml += (" <ImplementationClass>"
560: + ext.getImplementationClass() + "</ImplementationClass>\n");
561: xml += " </ExtensionAlgorithm>\n";
562: }
563:
564: xml += (" <DefaultAlgorithm>" + defaultCompression + "</DefaultAlgorithm>\n");
565: xml += " </CompressionConfiguration>\n";
566: xml += " <!-- The Public Key configuration, add or overide default public key implementations -->\n";
567: xml += " <PublicKeyConfiguration>\n";
568: it = pkExtensions.iterator();
569:
570: while (it.hasNext()) {
571: ext = (ExtensionAlgorithm) it.next();
572: xml += " <ExtensionAlgorithm>\n";
573: xml += (" <AlgorithmName>" + ext.getAlgorithmName() + "</AlgorithmName>\n");
574: xml += (" <ImplementationClass>"
575: + ext.getImplementationClass() + "</ImplementationClass>\n");
576: xml += " </ExtensionAlgorithm>\n";
577: }
578:
579: xml += (" <DefaultAlgorithm>" + defaultPublicKey + "</DefaultAlgorithm>\n");
580: it = pkFormats.iterator();
581:
582: String cls;
583:
584: while (it.hasNext()) {
585: cls = (String) it.next();
586: xml += (" <PublicKeyFormat ImplementationClass=\""
587: + cls + "\"/>\n");
588: }
589:
590: it = prvFormats.iterator();
591:
592: while (it.hasNext()) {
593: cls = (String) it.next();
594: xml += (" <PrivateKeyFormat ImplementationClass=\""
595: + cls + "\"/>\n");
596: }
597:
598: xml += (" <DefaultPublicFormat>" + defaultPublicFormat + "</DefaultPublicFormat>\n");
599: xml += (" <DefaultPrivateFormat>" + defaultPrivateFormat + "</DefaultPrivateFormat>\n");
600: xml += " </PublicKeyConfiguration>\n";
601: xml += " <!-- The Key Exchange configuration, add or overide default key exchange implementations -->\n";
602: xml += " <KeyExchangeConfiguration>\n";
603: it = kexExtensions.iterator();
604:
605: while (it.hasNext()) {
606: ext = (ExtensionAlgorithm) it.next();
607: xml += " <ExtensionAlgorithm>\n";
608: xml += (" <AlgorithmName>" + ext.getAlgorithmName() + "</AlgorithmName>\n");
609: xml += (" <ImplementationClass>"
610: + ext.getImplementationClass() + "</ImplementationClass>\n");
611: xml += " </ExtensionAlgorithm>\n";
612: }
613:
614: xml += (" <DefaultAlgorithm>" + defaultKeyExchange + "</DefaultAlgorithm>\n");
615: xml += " </KeyExchangeConfiguration>\n";
616: xml += " <!-- The Authentication configuration, add or overide default authentication implementations -->\n";
617: xml += " <AuthenticationConfiguration>\n";
618: it = authExtensions.iterator();
619:
620: while (it.hasNext()) {
621: ext = (ExtensionAlgorithm) it.next();
622: xml += " <ExtensionAlgorithm>\n";
623: xml += (" <AlgorithmName>" + ext.getAlgorithmName() + "</AlgorithmName>\n");
624: xml += (" <ImplementationClass>"
625: + ext.getImplementationClass() + "</ImplementationClass>\n");
626: xml += " </ExtensionAlgorithm>\n";
627: }
628:
629: xml += " </AuthenticationConfiguration>\n";
630: xml += "</SshAPIConfiguration>";
631:
632: return xml;
633: }
634: }
|