View Javadoc

    1   /*
    2    * Copyright 2009 University Corporation for Advanced Internet Development, Inc.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    * http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16
    17  package edu.internet2.middleware.shibboleth.idp;
    18
    19  import java.io.IOException;
    20  import java.io.PrintWriter;
    21  import java.net.InetAddress;
    22  import java.net.UnknownHostException;
    23
    24  import javax.servlet.ServletConfig;
    25  import javax.servlet.ServletException;
    26  import javax.servlet.http.HttpServlet;
    27  import javax.servlet.http.HttpServletRequest;
    28  import javax.servlet.http.HttpServletResponse;
    29
    30  import org.apache.commons.httpclient.HttpStatus;
    31  import org.joda.time.DateTime;
    32  import org.joda.time.chrono.ISOChronology;
    33  import org.joda.time.format.DateTimeFormatter;
    34  import org.joda.time.format.ISODateTimeFormat;
    35  import org.opensaml.xml.security.x509.X509Credential;
    36  import org.opensaml.xml.util.Base64;
    37  import org.opensaml.xml.util.DatatypeHelper;
    38  import org.opensaml.xml.util.LazyList;
    39  import org.slf4j.Logger;
    40  import org.slf4j.LoggerFactory;
    41
    42  import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolutionException;
    43  import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolver;
    44  import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfiguration;
    45  import edu.internet2.middleware.shibboleth.common.relyingparty.RelyingPartyConfigurationManager;
    46  import edu.internet2.middleware.shibboleth.idp.util.HttpServletHelper;
    47  import edu.internet2.middleware.shibboleth.idp.util.IPRange;
    48
    49  /** A Servlet for displaying the status of the IdP. */
    50  public class StatusServlet extends HttpServlet {
    51
    52      /** Serial version UID. */
    53      private static final long serialVersionUID = -5280549109235107879L;
    54
    55      private final String IP_PARAM_NAME = "AllowedIPs";
    56
    57      private final Logger log = LoggerFactory.getLogger(StatusServlet.class);
    58
    59      private LazyList<IPRange> allowedIPs;
    60
    61      /** Formatter used when print date/times. */
    62      private DateTimeFormatter dateFormat;
    63
    64      /** Time the IdP started up. */
    65      private DateTime startTime;
    66
    67      /** Attribute resolver used by the IdP. */
    68      private AttributeResolver<?> attributeResolver;
    69
    70      /** Relying party configuration manager used by the IdP. */
    71      private RelyingPartyConfigurationManager rpConfigManager;
    72
    73      /** {@inheritDoc} */
    74      public void init(ServletConfig config) throws ServletException {
    75          super.init(config);
    76
    77          allowedIPs = new LazyList<IPRange>();
    78
    79          String cidrBlocks = DatatypeHelper.safeTrimOrNullString(config.getInitParameter(IP_PARAM_NAME));
    80          if (cidrBlocks != null) {
    81              for (String cidrBlock : cidrBlocks.split(" ")) {
    82                  allowedIPs.add(IPRange.parseCIDRBlock(cidrBlock));
    83              }
    84          }
    85
    86          dateFormat = ISODateTimeFormat.dateTimeNoMillis();
    87          startTime = new DateTime(ISOChronology.getInstanceUTC());
    88          attributeResolver = HttpServletHelper.getAttributeResolver(config.getServletContext());
    89          rpConfigManager = HttpServletHelper.getRelyingPartyConfirmationManager(config.getServletContext());
    90      }
    91
    92      /** {@inheritDoc} */
    93      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    94          if (!isAuthenticated(request)) {
    95              response.sendError(HttpStatus.SC_UNAUTHORIZED);
    96              return;
    97          }
    98
    99          response.setContentType("text/plain");
    100         PrintWriter output = response.getWriter();
    101
    102         printOperatingEnvironmentInformation(output);
    103         output.println();
    104         printIdPInformation(output);
    105         output.println();
    106         printRelyingPartyConfigurationsInformation(output, request.getParameter("relyingParty"));
    107
    108         output.flush();
    109     }
    110
    111     /**
    112      * Checks whether the client is authenticated.
    113      *
    114      * @param request client request
    115      *
    116      * @return true if the client is authenticated, false if not
    117      */
    118     protected boolean isAuthenticated(HttpServletRequest request) throws ServletException {
    119         log.debug("Attempting to authenticate client '{}'", request.getRemoteAddr());
    120         try {
    121             InetAddress clientAddress = InetAddress.getByName(request.getRemoteAddr());
    122
    123             for (IPRange range : allowedIPs) {
    124                 if (range.contains(clientAddress)) {
    125                     return true;
    126                 }
    127             }
    128
    129             return false;
    130         } catch (UnknownHostException e) {
    131             throw new ServletException(e);
    132         }
    133     }
    134
    135     /**
    136      * Prints out information about the operating environment. This includes the operating system name, version and
    137      * architecture, the JDK version, available CPU cores, memory currently used by the JVM process, the maximum amount
    138      * of memory that may be used by the JVM, and the current time in UTC.
    139      *
    140      * @param out output writer to which information will be written
    141      */
    142     protected void printOperatingEnvironmentInformation(PrintWriter out) {
    143         Runtime runtime = Runtime.getRuntime();
    144
    145         out.println("### Operating Environment Information");
    146         out.println("operating_system: " + System.getProperty("os.name"));
    147         out.println("operating_system_version: " + System.getProperty("os.version"));
    148         out.println("operating_system_architecture: " + System.getProperty("os.arch"));
    149         out.println("jdk_version: " + System.getProperty("java.version"));
    150         out.println("available_cores: " + runtime.availableProcessors());
    151         out.println("used_memory: " + runtime.totalMemory() / 1048576 + "MB");
    152         out.println("maximum_memory: " + runtime.maxMemory() / 1048576 + "MB");
    153         out.println("current_time: " + new DateTime(ISOChronology.getInstanceUTC()).toString(dateFormat));
    154     }
    155
    156     /**
    157      * Prints out general IdP information. This includes IdP version, start up time, and whether the attribute resolver
    158      * is currently operational.
    159      *
    160      * @param out output writer to which information will be written
    161      */
    162     protected void printIdPInformation(PrintWriter out) {
    163         Package pkg = Version.class.getPackage();
    164
    165         out.println("### Identity Provider Information");
    166         out.println("idp_version: " + pkg.getImplementationVersion());
    167         out.println("idp_start_time: " + startTime.toString(dateFormat));
    168         try {
    169             attributeResolver.validate();
    170             out.println("attribute_resolver_valid: " + Boolean.TRUE);
    171         } catch (AttributeResolutionException e) {
    172             out.println("attribute_resolver_valid: " + Boolean.FALSE);
    173         }
    174     }
    175
    176     /**
    177      * Prints information about relying party configurations. If the given relying party is null then the configuration
    178      * for all relying parties is printed. If the relying party ID is not null then the relying party configurations for
    179      * that entity is printed.
    180      *
    181      * @param out output writer to which information will be written
    182      * @param relyingPartyId entity ID of the relying party whose configuration should be printed
    183      */
    184     protected void printRelyingPartyConfigurationsInformation(PrintWriter out, String relyingPartyId) {
    185         out.println("### Relying Party Configurations");
    186
    187         if (relyingPartyId == null) {
    188             for (RelyingPartyConfiguration config : rpConfigManager.getRelyingPartyConfigurations().values()) {
    189                 printRelyingPartyConfigurationInformation(out, config);
    190                 out.println();
    191             }
    192         } else {
    193             RelyingPartyConfiguration config = rpConfigManager.getRelyingPartyConfiguration(relyingPartyId);
    194             printRelyingPartyConfigurationInformation(out, config);
    195             out.println();
    196         }
    197     }
    198
    199     /**
    200      * Prints out the information for a specific relying party configuration. This information includes the relying
    201      * party or relying party group ID, the entity ID of the IdP when it responds when using this configuration, the
    202      * default authentication method used for this config, and configured communication profiles.
    203      *
    204      * @param out output writer to which information will be written
    205      * @param config the relying party configuration
    206      */
    207     protected void printRelyingPartyConfigurationInformation(PrintWriter out, RelyingPartyConfiguration config) {
    208         out.println("relying_party_id: " + config.getRelyingPartyId());
    209         out.println("idp_entity_id: " + config.getProviderId());
    210
    211         if (config.getDefaultAuthenticationMethod() != null) {
    212             out.println("default_authentication_method: " + config.getDefaultAuthenticationMethod());
    213         } else {
    214             out.println("default_authentication_method: none");
    215         }
    216
    217         try {
    218             X509Credential signingCredential = (X509Credential) config.getDefaultSigningCredential();
    219             out
    220                     .println("default_signing_tls_key: "
    221                             + Base64.encodeBytes(signingCredential.getEntityCertificate().getEncoded(),
    222                                     Base64.DONT_BREAK_LINES));
    223         } catch (Throwable t) {
    224             // swallow error
    225         }
    226
    227         for (String profileId : config.getProfileConfigurations().keySet()) {
    228             out.println("configured_communication_profile: " + profileId);
    229         }
    230     }
    231 }