File: AbstractJdbc4MakeSSL.java

package info (click to toggle)
libpgjava 9.2-1002-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 4,308 kB
  • ctags: 4,503
  • sloc: java: 37,623; xml: 3,376; makefile: 22; sh: 10
file content (159 lines) | stat: -rw-r--r-- 5,805 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*-------------------------------------------------------------------------
*
* Copyright (c) 2004-2011, PostgreSQL Global Development Group
*
*
*-------------------------------------------------------------------------
*/
package org.postgresql.ssl.jdbc4;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

import org.postgresql.core.Logger;
import org.postgresql.core.PGStream;
import org.postgresql.util.GT;
import org.postgresql.util.PSQLException;
import org.postgresql.util.PSQLState;

public class AbstractJdbc4MakeSSL {
  
    /**
     * Instantiates a class using the appropriate constructor.
     * If a constructor with a single Propertiesparameter exists, it is
     * used. Otherwise, if tryString is true a constructor with
     * a single String argument is searched if it fails, or tryString is true
     * a no argument constructor is tried.
     * @param classname Nam of the class to instantiate
     * @param info parameter to pass as Properties
     * @param tryString weather to look for a single String argument constructor
     * @param stringarg parameter to pass as String
     * @return the instantiated class
     * @throws ClassNotFoundException
     * @throws SecurityException
     * @throws NoSuchMethodException
     * @throws IllegalArgumentException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public static Object instantiate(String classname, Properties info, boolean tryString, String stringarg) 
        throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException,
        InstantiationException, IllegalAccessException, InvocationTargetException
    {
      Object[] args = {info};
      Constructor ctor = null;
      Class cls;
      cls = Class.forName(classname);
      try
      {         
          ctor = cls.getConstructor(new Class[]{Properties.class});
      }
      catch (NoSuchMethodException nsme)
      {
        if (tryString)
        {
          try
          {
              ctor = cls.getConstructor(new Class[]{String.class});
              args = new String[]{stringarg};
          }
          catch (NoSuchMethodException nsme2)
          {
            tryString = false;
          }
        }
        if (!tryString)
        {
          ctor = cls.getConstructor((Class[])null);
          args = null;          
        }
      }
      return ctor.newInstance(args);
    }
    
    public static void convert(PGStream stream, Properties info, Logger logger) throws PSQLException, IOException {
        logger.debug("converting regular socket connection to ssl");

        SSLSocketFactory factory;

        String sslmode = info.getProperty("sslmode");
        // Use the default factory if no specific factory is requested
        // unless sslmode is set
        String classname = info.getProperty("sslfactory");
        if (classname == null)
        {
          //If sslmode is set, use the libp compatible factory
          if (sslmode!=null)
          {
            factory = new LibPQFactory(info);
          }
          else
          {
            factory = (SSLSocketFactory)SSLSocketFactory.getDefault();
          }
        }
        else
        {
            try
            {
                factory = (SSLSocketFactory)instantiate(classname, info, true, info.getProperty("sslfactoryarg"));
            }
            catch (Exception e)
            {
                throw new PSQLException(GT.tr("The SSLSocketFactory class provided {0} could not be instantiated.", classname), PSQLState.CONNECTION_FAILURE, e);
            }
        }

        SSLSocket newConnection;
        try
        {
          newConnection = (SSLSocket)factory.createSocket(stream.getSocket(), stream.getHostSpec().getHost(), stream.getHostSpec().getPort(), true);
          newConnection.startHandshake(); //We must invoke manually, otherwise the exceptions are hidden
        }
        catch (IOException ex) {
          if (factory instanceof LibPQFactory)
          { //throw any KeyManager exception
            ((LibPQFactory)factory).throwKeyManagerException();
          }
          throw new PSQLException(GT.tr("SSL error: {0}", ex.getMessage()), PSQLState.CONNECTION_FAILURE, ex);
        }
        
        String sslhostnameverifier = info.getProperty("sslhostnameverifier");
        if (sslhostnameverifier!=null)
        {
          HostnameVerifier hvn;
          try
          {
            hvn = (HostnameVerifier)instantiate(sslhostnameverifier, info, false, null);
          }
          catch (Exception e)
          {
              throw new PSQLException(GT.tr("The HostnameVerifier class provided {0} could not be instantiated.", sslhostnameverifier), PSQLState.CONNECTION_FAILURE, e);
          }
          if (!hvn.verify(stream.getHostSpec().getHost(), newConnection.getSession()))
          {
            throw new PSQLException(GT.tr("The hostname {0} could not be verified by hostnameverifier {1}.", new Object[]{stream.getHostSpec().getHost(), sslhostnameverifier}), PSQLState.CONNECTION_FAILURE);
          }
        } else {
          if ("verify-full".equals(sslmode) && factory instanceof LibPQFactory)
          {
            if (!(((LibPQFactory)factory).verify(stream.getHostSpec().getHost(), newConnection.getSession())))
            {
              throw new PSQLException(GT.tr("The hostname {0} could not be verified.", stream.getHostSpec().getHost()), PSQLState.CONNECTION_FAILURE);
            }
          }

        }
        stream.changeSocket(newConnection);
    }

}