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