📄 vpptransaction.java
字号:
/* * ==================================================================== * The Vovida Software License, Version 1.0 * * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names "VOCAL", "Vovida Open Communication Application Library", * and "Vovida Open Communication Application Library (VOCAL)" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor * may "VOCAL" appear in their name, without prior written * permission of Vovida Networks, Inc. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * ==================================================================== * * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc. For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */package vocal.comm;import java.net.Socket;import java.net.InetAddress;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;import vocal.comm.TrustAllTrustManager;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSocket;import javax.net.SocketFactory;import java.io.*;import javax.swing.JOptionPane;import javax.swing.JFrame;/** * This class is an abstraction to communicate with the provisioning server * user the VPP (Vovida Provisioning Protocol) protocol. * * Allows you open a connection, make any number of put and get operations, * and close the connection, abstracting away most of the details of the * transaction. */public class VPPTransaction implements Transaction{ public static int WRITE_TO_FILE = 1; public static int WRITE_TO_PSERVER = 2; public static int ERROR_MEANS_NO_SUCH_FILE = 0; public static int ERROR_MEANS_PERM_DENIED = 1; public static int ERROR_MEANS_AUTH_FAILED = 2; /** * True when this connection has been closed. * This is used to stop reconnect attempts. */ private boolean isClosed = false; /** * the size (in characters) of the buffer used to save up output from the * server */ private static final int blockSize = 4096; /** * Indicates whether there is currently a valid connection open to the * server. */ private boolean connected = false; /** * Indicates whether there is the connection has been authenticated by * server. */ private boolean authenticated = false; /** * The timeout for read operations from a socket input stream. This is used * to activate non-blocking io. Units are milliseconds. */ private static final int SOCKET_TIMEOUT = 12000; protected Socket socket; protected BufferedReader fromSocket; protected OutputStreamWriter toSocket; private Reconnect reconnect = null; private String host; private int port; public VPPTransaction(String server, int portNo) throws VPPException { host = server; port = portNo; // try and catch errors we know about, throw anything else try { System.out.println("creating socket to host " + server + ", port " + port); Socket tempSocket = new Socket(InetAddress.getByName(server), port); tempSocket.setSoTimeout(SOCKET_TIMEOUT); // because we are not connected yet, send manually. OutputStreamWriter tempToSocket = new OutputStreamWriter(tempSocket.getOutputStream());// BufferedReader tempFromSocket = new BufferedReader// (new InputStreamReader(tempSocket.getInputStream())); InputStreamReader tempFromSocket = new InputStreamReader(tempSocket.getInputStream()); tempToSocket.write("TLS . VPP/1.1\n"); tempToSocket.flush(); System.out.println("wrote TLS line to temp socket"); char nextCharacter; StringBuffer line = new StringBuffer(); while ((nextCharacter = (char) tempFromSocket.read()) != '\n') { line.append(nextCharacter); } StringBuffer contentLength = new StringBuffer(); while ((nextCharacter = (char) tempFromSocket.read()) != '\n') { contentLength.append(nextCharacter); } String response = new String(line); System.out.println("got response " + response); if ("200 OK".equals(response)) { SSLContext sslcontext; try { sslcontext = SSLContext.getInstance( "TLS"); } catch(java.security.NoSuchAlgorithmException ex) { // big error ex.printStackTrace(); String message = "The program could not open a socket to " + "the server \n" + server + " on port " + port + "\n\n" + "Reason: " + ex.getMessage(); throw new VPPLowLevelException(ex, message); } SSLSocketFactory sf; try { sslcontext.init( null, // No KeyManager required new TrustManager[] { new vocal.comm.TrustAllTrustManager() }, new java.security.SecureRandom()); } catch(java.security.KeyManagementException ex) { // big error ex.printStackTrace(); String message = "The program could not open a socket to " + "the server \n" + server + " on port " + port + "\n\n" + "Reason: " + ex.getMessage(); throw new VPPLowLevelException(ex, message); } sf = ( SSLSocketFactory) sslcontext.getSocketFactory();// // pserver can communicate on SSL socket// = (SSLSocketFactory)SSLSocketFactory.getDefault(); SSLSocket ssl = (SSLSocket)sf.createSocket(tempSocket, host, port, true); String list2[] = { "TLSv1" }; ssl.setEnabledProtocols(list2); String list[]; list = ssl.getEnabledProtocols(); System.out.println("protocols: " ); for (int i=0; i<list.length; i++) { System.out.println(" " + list[i]); } System.out.println("client: " + ssl.getUseClientMode()); // explicitly create the connection ssl.startHandshake(); socket = ssl; // disable blocking I/O by setting a timeout on the // socketInputStream.read operation socket.setSoTimeout(SOCKET_TIMEOUT); } else { //pserver cannot communicate on SSL socket JOptionPane.showMessageDialog(new JFrame(), "This connection is not encrypted", "Warning", JOptionPane.WARNING_MESSAGE); socket = tempSocket; } } catch (IOException ex) { ex.printStackTrace(); String message = "The program could not open a socket to " + "the server \n" + server + " on port " + port + "\n\n" + "Reason: " + ex.getMessage(); throw new VPPLowLevelException(ex, message); } try { fromSocket = new BufferedReader(new InputStreamReader(socket.getInputStream())); } catch (IOException ex) { String message = "The server was contacted, but could " + "not be read from.\n\n" + "Reason: " + ex.getMessage(); throw new VPPLowLevelException(ex, message); } try { toSocket = new OutputStreamWriter(socket.getOutputStream()); } catch (IOException ex) { String message = "The server was contacted, but could " + "not be written to.\n\n" + "Reason: " + ex.getMessage(); throw new VPPLowLevelException(ex, message); } connected = true; // if we got here things must be ok... } /** * Read the status line (200... or 400...) of our VPP transaction * and verify that the status says OK. It is expected that the stream is * at the right position to read the status. */ protected String getStatusLine(int flag) throws VPPException { String statusLine = readLineFromSocket(); System.out.println("---TRACE--- VPPTransaction:reply - " + statusLine + Thread.currentThread()); // Our protocol demands that status line must start with the // return code. if (statusLine.startsWith("400")) { System.out.println("---TRACE--- VPPTransaction:" + "Got 400 -- Throwing exception"); if (flag == ERROR_MEANS_NO_SUCH_FILE) { throw new VPPNoSuchFileException("File Not Found"); } else if (flag == ERROR_MEANS_AUTH_FAILED) { /* this happens during normal operation */ return statusLine; } else { throw new VPPPermissionException("Permission Denied"); } } else if (!statusLine.startsWith("200")) { // throw the malformed message since we should get // one of 200 or 400 throw new VPPMalformedMsgException("The server did not " + "respond properly" + " to the command. " + "The result is: " + statusLine); } // else 200, so ok return statusLine; } /** * Read the content length line of our VPP transaction and verify * that it starts with the "Content-Length: " string. It assumes that the * underlying streams for this connection are at the right position to read * the content length. */ protected int getContentLength() throws VPPException { String contentLengthLine = readLineFromSocket(); // Verify that the line starts with "Content-Length: " if (!contentLengthLine.startsWith("Content-Length: ")) { throw new VPPMalformedMsgException("The Content-Length line from the server" + "was missing or malformed.\n" + "Its contents were:\n \"" + contentLengthLine + "\"."); } // we know the first 16 are the Content-Length, try to get the # String contentLengthAsString; contentLengthAsString = contentLengthLine.substring(16); int contentLength; try { contentLength = Integer.parseInt(contentLengthAsString); } catch (NumberFormatException e) { throw new VPPMalformedMsgException("The Content-Length line was corrupted\n" + "The contents were: \n \"" + contentLengthLine + "\"."); } return contentLength; } protected String getContents(int contentLength) throws IOException, VPPException { char[] buffer = new char[contentLength]; int totalCharsRead = 0; int charsRead = 0; StringBuffer response = new StringBuffer(); while (totalCharsRead < contentLength) { try { charsRead = fromSocket.read(buffer, 0, contentLength); } catch (IOException e) { System.out.println("Reconnecting"); reconnect(); } if (charsRead == -1) { throw new VPPMalformedMsgException("There was a problem in reading" + "the response:\n Content-Length was reported as " + contentLength + ", \n but the stream closed after only " + totalCharsRead + " characters."); } totalCharsRead += charsRead; response.append(buffer, 0, charsRead); } if (totalCharsRead < contentLength) { throw new VPPMalformedMsgException("There was a problem in reading the response: " + "\nContent-Length was reported as " + contentLength + ", \nbut the stream closed after only " + totalCharsRead + " characters."); } return response.toString();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -