<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.guacamole.auth.radius;

import com.google.inject.Inject;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleUnsupportedException;
import org.apache.guacamole.environment.LocalEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.jradius.client.RadiusClient;
import net.jradius.exception.RadiusException;
import net.jradius.packet.RadiusPacket;
import net.jradius.packet.AccessRequest;
import net.jradius.dictionary.*;
import net.jradius.packet.attribute.AttributeList;
import net.jradius.packet.attribute.RadiusAttribute;
import net.jradius.client.auth.EAPTLSAuthenticator;
import net.jradius.client.auth.EAPTTLSAuthenticator;
import net.jradius.client.auth.RadiusAuthenticator;
import net.jradius.client.auth.PEAPAuthenticator;
import net.jradius.packet.attribute.AttributeFactory;
import net.jradius.packet.AccessChallenge;
import net.jradius.packet.RadiusResponse;

/**
 * Service for creating and managing connections to RADIUS servers.
 */
public class RadiusConnectionService {

    /**
     * Logger for this class.
     */
    private final Logger logger = LoggerFactory.getLogger(RadiusConnectionService.class);

    /**
     * Service for retrieving RADIUS server configuration information.
     */
    @Inject
    private ConfigurationService confService;


    /**
     * The RADIUS client;
     */
    private RadiusClient radiusClient;

    /**
     * Creates a new instance of RadiusClient, configured with parameters
     * from guacamole.properties.
     *
     * @throws GuacamoleException
     *     If an error occurs while parsing guacamole.properties, or if the
     *     configuration of RadiusClient fails.
     */
    private void createRadiusConnection() {

        // Create the RADIUS client with the configuration parameters
        try {
            radiusClient = new RadiusClient(InetAddress.getByName(confService.getRadiusServer()),
                                            confService.getRadiusSharedSecret(),
                                            confService.getRadiusAuthPort(),
                                            confService.getRadiusAcctPort(),
                                            confService.getRadiusTimeout());
        }
        catch (GuacamoleException e) {
            logger.error("Unable to initialize RADIUS client: {}", e.getMessage());
            logger.debug("Failed to init RADIUS client.", e);
        }
        catch (UnknownHostException e) {
            logger.error("Unable to resolve host: {}", e.getMessage());
            logger.debug("Failed to resolve host.", e);
        }
        catch (IOException e) {
            logger.error("Unable to communicate with host: {}", e.getMessage());
            logger.debug("Failed to communicate with host.", e);
        }

    }

    /**
     * Creates a new instance of RadiusAuthentictor, configured with
     * parameters specified within guacamole.properties.
     *
     * @return
     *     A new RadiusAuthenticator instance which has been configured
     *     with parameters from guacamole.properties, or null if
     *     configuration fails.
     *
     */
    private RadiusAuthenticator setupRadiusAuthenticator() throws GuacamoleException {

        // If we don't have a radiusClient object, yet, don't go any further.
        if (radiusClient == null) {
            logger.error("RADIUS client hasn't been set up, yet.");
            logger.debug("We can't run this method until the RADIUS client has been set up.");
            return null;
        }

        String caFile;
        String caPassword;
        String caType;
        String keyFile;
        String keyPassword;
        String innerProtocol;
        LocalEnvironment guacEnv;
        String basePath;

        // Pull configuration parameters from guacamole.properties
        guacEnv = new LocalEnvironment();
        basePath = guacEnv.getGuacamoleHome().getAbsolutePath() + '/';
        caFile = confService.getRadiusCAFile();
        caPassword = <PASSWORD>Service.getRadiusCAPassword();
        keyFile = confService.getRadiusKeyFile();
        keyPassword = confService.getRadiusKeyPassword();
        innerProtocol = confService.getRadiusEAPTTLSInnerProtocol();
            
        RadiusAuthenticator radAuth = radiusClient.getAuthProtocol(confService.getRadiusAuthProtocol());
        if (radAuth == null)
            throw new GuacamoleException("Could not get a valid RadiusAuthenticator for specified protocol: " + confService.getRadiusAuthProtocol());

        // If we're using any of the TLS protocols, we need to configure them
        if (radAuth instanceof PEAPAuthenticator || 
            radAuth instanceof EAPTLSAuthenticator || 
            radAuth instanceof EAPTTLSAuthenticator) {

            if (caFile != null) {
                ((EAPTLSAuthenticator)radAuth).setCaFile(basePath + caFile);
                ((EAPTLSAuthenticator)radAuth).setCaFileType(confService.getRadiusCAType());
                if (caPassword != null)
                    ((EAPTLSAuthenticator)radAuth).setCaPassword(caPassword);
            }

            if (keyPassword != null)
                ((EAPTLSAuthenticator)radAuth).setKeyPassword(keyPassword);

            ((EAPTLSAuthenticator)radAuth).setKeyFile(basePath + keyFile);
            ((EAPTLSAuthenticator)radAuth).setKeyFileType(confService.getRadiusKeyType());
            ((EAPTLSAuthenticator)radAuth).setTrustAll(confService.getRadiusTrustAll());

        }

        // If we're using EAP-TTLS, we need to define tunneled protocol
        if (radAuth instanceof EAPTTLSAuthenticator) {

            if (innerProtocol == null)<commit_msg>GUACAMOLE-197: Use java.io.File for filename operations, rather than relying on platform-specific assumptions.<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.guacamole.auth.radius;

import com.google.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.GuacamoleUnsupportedException;
import org.apache.guacamole.environment.LocalEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.jradius.client.RadiusClient;
import net.jradius.exception.RadiusException;
import net.jradius.packet.RadiusPacket;
import net.jradius.packet.AccessRequest;
import net.jradius.dictionary.*;
import net.jradius.packet.attribute.AttributeList;
import net.jradius.packet.attribute.RadiusAttribute;
import net.jradius.client.auth.EAPTLSAuthenticator;
import net.jradius.client.auth.EAPTTLSAuthenticator;
import net.jradius.client.auth.RadiusAuthenticator;
import net.jradius.client.auth.PEAPAuthenticator;
import net.jradius.packet.attribute.AttributeFactory;
import net.jradius.packet.AccessChallenge;
import net.jradius.packet.RadiusResponse;

/**
 * Service for creating and managing connections to RADIUS servers.
 */
public class RadiusConnectionService {

    /**
     * Logger for this class.
     */
    private final Logger logger = LoggerFactory.getLogger(RadiusConnectionService.class);

    /**
     * Service for retrieving RADIUS server configuration information.
     */
    @Inject
    private ConfigurationService confService;


    /**
     * The RADIUS client;
     */
    private RadiusClient radiusClient;

    /**
     * Creates a new instance of RadiusClient, configured with parameters
     * from guacamole.properties.
     *
     * @throws GuacamoleException
     *     If an error occurs while parsing guacamole.properties, or if the
     *     configuration of RadiusClient fails.
     */
    private void createRadiusConnection() {

        // Create the RADIUS client with the configuration parameters
        try {
            radiusClient = new RadiusClient(InetAddress.getByName(confService.getRadiusServer()),
                                            confService.getRadiusSharedSecret(),
                                            confService.getRadiusAuthPort(),
                                            confService.getRadiusAcctPort(),
                                            confService.getRadiusTimeout());
        }
        catch (GuacamoleException e) {
            logger.error("Unable to initialize RADIUS client: {}", e.getMessage());
            logger.debug("Failed to init RADIUS client.", e);
        }
        catch (UnknownHostException e) {
            logger.error("Unable to resolve host: {}", e.getMessage());
            logger.debug("Failed to resolve host.", e);
        }
        catch (IOException e) {
            logger.error("Unable to communicate with host: {}", e.getMessage());
            logger.debug("Failed to communicate with host.", e);
        }

    }

    /**
     * Creates a new instance of RadiusAuthentictor, configured with
     * parameters specified within guacamole.properties.
     *
     * @return
     *     A new RadiusAuthenticator instance which has been configured
     *     with parameters from guacamole.properties, or null if
     *     configuration fails.
     *
     */
    private RadiusAuthenticator setupRadiusAuthenticator() throws GuacamoleException {

        // If we don't have a radiusClient object, yet, don't go any further.
        if (radiusClient == null) {
            logger.error("RADIUS client hasn't been set up, yet.");
            logger.debug("We can't run this method until the RADIUS client has been set up.");
            return null;
        }

        // Pull configuration parameters from guacamole.properties
        LocalEnvironment guacEnv = new LocalEnvironment();
        String guacHome = guacEnv.getGuacamoleHome().getAbsolutePath();
        String caFile = confService.getRadiusCAFile();
        String caPassword = confService.getRadiusCAPassword();
        String keyFile = confService.getRadiusKeyFile();
        String keyPassword = confService.getRadiusKeyPassword();
        String innerProtocol = confService.getRadiusEAPTTLSInnerProtocol();
            
        RadiusAuthenticator radAuth = radiusClient.getAuthProtocol(confService.getRadiusAuthProtocol());
        if (radAuth == null)
            throw new GuacamoleException("Could not get a valid RadiusAuthenticator for specified protocol: " + confService.getRadiusAuthProtocol());

        // If we're using any of the TLS protocols, we need to configure them
        if (radAuth instanceof PEAPAuthenticator || 
            radAuth instanceof EAPTLSAuthenticator || 
            radAuth instanceof EAPTTLSAuthenticator) {

            if (caFile != null) {
                ((EAPTLSAuthenticator)radAuth).setCaFile((new File(guacHome, caFile)).toString());
                ((EAPTLSAuthenticator)radAuth).setCaFileType(confService.getRadiusCAType());
                if (caPassword != null)
                    ((EAPTLSAuthenticator)radAuth).setCaPassword(caPassword);
            }

            if (keyPassword != null)
                ((EAPTLSAuthenticator)radAuth).setKeyPassword(keyPassword);

            ((EAPTLSAuthenticator)radAuth).setKeyFile((new File(guacHome, keyFile)).toString());
            ((EAPTLSAuthenticator)radAuth).setKeyFileType(confService.getRadiusKeyType());
            ((EAPTLSAuthenticator)radAuth).setTrustAll(confService.getRadiusTrustAll());

        }

        // If we're using EAP-TTLS, we need to define tunneled protocol
        if (radAuth instanceof EAPTTLSAuthenticator) {

            if (innerProtocol == null)
{'fraction_non_alphanumeric': 0.08395466746197436, 'fraction_numerical': 0.0011184014315538324, 'mean_word_length': 2.8498851894374284, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7065339', 'n_tokens_mistral': 3471, 'n_tokens_neox': 3403, 'n_words': 957}