2 * ============LICENSE_START====================================================
4 * ===========================================================================
5 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6 * ===========================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END====================================================
21 package org.onap.aaf.auth.server;
23 import java.io.IOException;
24 import java.net.Inet4Address;
25 import java.net.InetAddress;
26 import java.util.Properties;
28 import javax.servlet.Filter;
29 import javax.servlet.FilterChain;
30 import javax.servlet.ServletException;
31 import javax.servlet.ServletRequest;
32 import javax.servlet.ServletResponse;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.HttpServletResponse;
36 import org.eclipse.jetty.http.HttpVersion;
37 import org.eclipse.jetty.server.HttpConfiguration;
38 import org.eclipse.jetty.server.HttpConnectionFactory;
39 import org.eclipse.jetty.server.Request;
40 import org.eclipse.jetty.server.SecureRequestCustomizer;
41 import org.eclipse.jetty.server.Server;
42 import org.eclipse.jetty.server.ServerConnector;
43 import org.eclipse.jetty.server.SslConnectionFactory;
44 import org.eclipse.jetty.server.handler.AbstractHandler;
45 import org.eclipse.jetty.util.ssl.SslContextFactory;
46 import org.onap.aaf.auth.org.OrganizationException;
47 import org.onap.aaf.auth.rserv.RServlet;
48 import org.onap.aaf.cadi.CadiException;
49 import org.onap.aaf.cadi.LocatorException;
50 import org.onap.aaf.cadi.Access.Level;
51 import org.onap.aaf.cadi.config.Config;
52 import org.onap.aaf.cadi.config.SecurityInfo;
53 import org.onap.aaf.misc.env.Trans;
54 import org.onap.aaf.misc.env.util.Split;
55 import org.onap.aaf.misc.rosetta.env.RosettaEnv;
58 public class JettyServiceStarter<ENV extends RosettaEnv, TRANS extends Trans> extends AbsServiceStarter<ENV,TRANS> {
60 private boolean secure;
62 public JettyServiceStarter(final AbsService<ENV,TRANS> service) throws OrganizationException {
68 * Specifically set this Service starter to Insecure (HTTP) Mode.
71 public JettyServiceStarter<ENV,TRANS> insecure() {
77 // public void _propertyAdjustment() {
78 // Properties props = access().getProperties();
79 // Object temp = null;
80 // // Critical - if no Security Protocols set, then set it. We'll just get messed up if not
81 // if((temp=props.get(Config.CADI_PROTOCOLS))==null) {
82 // if((temp=props.get(Config.HTTPS_PROTOCOLS))==null) {
83 // props.put(Config.CADI_PROTOCOLS, SecurityInfo.HTTPS_PROTOCOLS_DEFAULT);
85 // props.put(Config.CADI_PROTOCOLS, temp);
89 // if("1.7".equals(System.getProperty("java.specification.version"))) {
90 // System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT);
92 // System.setProperty(Config.HTTPS_CIPHER_SUITES, temp.toString());
96 public void _propertyAdjustment() {
97 // System.setProperty("com.sun.management.jmxremote.port", "8081");
98 Properties props = access().getProperties();
99 Object httpproto = null;
100 // Critical - if no Security Protocols set, then set it. We'll just get messed up if not
101 if((httpproto=props.get(Config.CADI_PROTOCOLS))==null) {
102 if((httpproto=props.get(Config.HTTPS_PROTOCOLS))==null) {
103 props.put(Config.CADI_PROTOCOLS, (httpproto=SecurityInfo.HTTPS_PROTOCOLS_DEFAULT));
105 props.put(Config.CADI_PROTOCOLS, httpproto);
109 if("1.7".equals(System.getProperty("java.specification.version")) && (httpproto==null || (httpproto instanceof String && ((String)httpproto).contains("TLSv1.2")))) {
110 System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT);
115 public void _start(RServlet<TRANS> rserv) throws Exception {
116 String hostname = access().getProperty(Config.HOSTNAME, null);
118 hostname = Inet4Address.getLocalHost().getHostName();
120 final int port = Integer.parseInt(access().getProperty("port","0"));
121 final String keystore = access().getProperty(Config.CADI_KEYSTORE, null);
122 final int IDLE_TIMEOUT = Integer.parseInt(access().getProperty(Config.AAF_CONN_IDLE_TIMEOUT, Config.AAF_CONN_IDLE_TIMEOUT_DEF));
123 Server server = new Server();
125 ServerConnector conn;
127 if(!secure || keystore==null) {
128 conn = new ServerConnector(server);
133 String keystorePassword = access().getProperty(Config.CADI_KEYSTORE_PASSWORD, null);
134 if(keystorePassword==null) {
135 throw new CadiException("No Keystore Password configured for " + keystore);
137 SslContextFactory sslContextFactory = new SslContextFactory();
138 sslContextFactory.setKeyStorePath(keystore);
140 sslContextFactory.setKeyStorePassword(temp=access().decrypt(keystorePassword, true)); // don't allow unencrypted
141 sslContextFactory.setKeyManagerPassword(temp);
142 temp=null; // don't leave lying around
144 String truststore = access().getProperty(Config.CADI_TRUSTSTORE, null);
145 if(truststore!=null) {
146 String truststorePassword = access().getProperty(Config.CADI_TRUSTSTORE_PASSWORD, null);
147 if(truststorePassword==null) {
148 throw new CadiException("No Truststore Password configured for " + truststore);
150 sslContextFactory.setTrustStorePath(truststore);
151 sslContextFactory.setTrustStorePassword(access().decrypt(truststorePassword, true));
153 // Be able to accept only certain protocols, i.e. TLSv1.1+
154 final String[] protocols = Split.splitTrim(',', access().getProperty(Config.CADI_PROTOCOLS, SecurityInfo.HTTPS_PROTOCOLS_DEFAULT));
155 sslContextFactory.setIncludeProtocols(protocols);
157 // Want to use Client Certificates, if they exist.
158 sslContextFactory.setWantClientAuth(true);
160 // Optional future checks.
161 // sslContextFactory.setValidateCerts(true);
162 // sslContextFactory.setValidatePeerCerts(true);
163 // sslContextFactory.setEnableCRLDP(false);
164 // sslContextFactory.setEnableOCSP(false);
165 String certAlias = access().getProperty(Config.CADI_ALIAS, null);
166 if(certAlias!=null) {
167 sslContextFactory.setCertAlias(certAlias);
170 HttpConfiguration httpConfig = new HttpConfiguration();
171 httpConfig.setSecureScheme(protocol);
172 httpConfig.setSecurePort(port);
173 httpConfig.addCustomizer(new SecureRequestCustomizer());
174 // httpConfig.setOutputBufferSize(32768); Not sure why take this setting
176 conn = new ServerConnector(server,
177 new SslConnectionFactory(sslContextFactory,HttpVersion.HTTP_1_1.asString()),
178 new HttpConnectionFactory(httpConfig)
183 // TODO trying to figure out how to set up/log ports
184 // MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
185 // MBeanContainer mbContainer=new MBeanContainer(mbeanServer);
186 // server.addEventListener(mbContainer);
187 // server.addBean(mbContainer);
189 // Add loggers MBean to server (will be picked up by MBeanContainer above)
190 // server.addBean(Log.getLog());
192 conn.setHost(hostname);
194 conn.setIdleTimeout(IDLE_TIMEOUT);
195 server.addConnector(conn);
197 server.setHandler(new AbstractHandler() {
198 private FilterChain fc = buildFilterChain(service,new FilterChain() {
200 public void doFilter(ServletRequest req, ServletResponse resp) throws IOException, ServletException {
201 rserv.service(req, resp);
206 public void handle(String target, Request baseRequest, HttpServletRequest hreq, HttpServletResponse hresp) throws IOException, ServletException {
208 fc.doFilter(hreq,hresp);
209 } catch (Exception e) {
210 service.access.log(e, "Error Processing " + target);
211 hresp.setStatus(500 /* Service Error */);
213 baseRequest.setHandled(true);
219 access().printf(Level.INIT, "Starting service on %s:%d (%s)",hostname,port,InetAddress.getLocalHost().getHostAddress());
221 access().log(Level.INIT,server.dump());
222 } catch (Exception e) {
223 access().log(e,"Error starting " + service.app_name);
224 String doExit = access().getProperty("cadi_exitOnFailure", "true");
225 if (doExit == "true") {
232 register(service.registrants(port));
233 access().printf(Level.INIT, "Starting Jetty Service for %s, version %s, on %s://%s:%d", service.app_name,service.app_version,protocol,hostname,port);
235 } catch(Exception e) {
236 access().log(e,"Error registering " + service.app_name);
237 String doExit = access().getProperty("cadi_exitOnFailure", "true");
238 if (doExit == "true") {
246 private FilterChain buildFilterChain(final AbsService<?,?> as, final FilterChain doLast) throws CadiException, LocatorException {
247 Filter[] filters = as.filters();
248 FilterChain fc = doLast;
249 for(int i=filters.length-1;i>=0;--i) {
250 fc = new FCImpl(filters[i],fc);
255 private class FCImpl implements FilterChain {
257 private FilterChain next;
259 public FCImpl(final Filter f, final FilterChain fc) {
265 public void doFilter(ServletRequest req, ServletResponse resp) throws IOException, ServletException {
266 f.doFilter(req,resp, next);