/**
 * 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.hadoop.security;

import static org.junit.Assert.*;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;

import javax.security.auth.kerberos.KerberosPrincipal;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.net.NetUtils;
import org.apache.hadoop.security.token.Token;
import org.junit.Test;
import org.mockito.Mockito;

public class TestSecurityUtil {
  @Test
  public void isOriginalTGTReturnsCorrectValues() {
    assertTrue(SecurityUtil.isTGSPrincipal
        (new KerberosPrincipal("krbtgt/foo@foo")));
    assertTrue(SecurityUtil.isTGSPrincipal
        (new KerberosPrincipal("krbtgt/foo.bar.bat@foo.bar.bat")));
    assertFalse(SecurityUtil.isTGSPrincipal
        (null));
    assertFalse(SecurityUtil.isTGSPrincipal
        (new KerberosPrincipal("blah")));
    assertFalse(SecurityUtil.isTGSPrincipal
        (new KerberosPrincipal("")));
    assertFalse(SecurityUtil.isTGSPrincipal
        (new KerberosPrincipal("krbtgt/hello")));
    assertFalse(SecurityUtil.isTGSPrincipal
        (new KerberosPrincipal("/@")));
    assertFalse(SecurityUtil.isTGSPrincipal
        (new KerberosPrincipal("krbtgt/foo@FOO")));
  }
  
  private void verify(String original, String hostname, String expected)
      throws IOException {
    assertEquals(expected,
                 SecurityUtil.getServerPrincipal(original, hostname));

    InetAddress addr = mockAddr(hostname);
    assertEquals(expected,
                 SecurityUtil.getServerPrincipal(original, addr));
  }

  private InetAddress mockAddr(String reverseTo) {
    InetAddress mock = Mockito.mock(InetAddress.class);
    Mockito.doReturn(reverseTo).when(mock).getCanonicalHostName();
    return mock;
  }
  
  @Test
  public void testGetServerPrincipal() throws IOException {
    String service = "hdfs/";
    String realm = "@REALM";
    String hostname = "foohost";
    String userPrincipal = "foo@FOOREALM";
    String shouldReplace = service + SecurityUtil.HOSTNAME_PATTERN + realm;
    String replaced = service + hostname + realm;
    verify(shouldReplace, hostname, replaced);
    String shouldNotReplace = service + SecurityUtil.HOSTNAME_PATTERN + "NAME"
        + realm;
    verify(shouldNotReplace, hostname, shouldNotReplace);
    verify(userPrincipal, hostname, userPrincipal);
    // testing reverse DNS lookup doesn't happen
    InetAddress notUsed = Mockito.mock(InetAddress.class);
    assertEquals(shouldNotReplace,
                 SecurityUtil.getServerPrincipal(shouldNotReplace, notUsed));
    Mockito.verify(notUsed, Mockito.never()).getCanonicalHostName();
  }

  @Test
  public void testPrincipalsWithLowerCaseHosts() throws IOException {
    String service = "xyz/";
    String realm = "@REALM";
    String principalInConf = service + SecurityUtil.HOSTNAME_PATTERN + realm;
    String hostname = "FooHost";
    String principal = service + hostname.toLowerCase() + realm;
    verify(principalInConf, hostname, principal);
  }

  @Test
  public void testLocalHostNameForNullOrWild() throws Exception {
    String local = SecurityUtil.getLocalHostName();
    assertEquals("hdfs/" + local + "@REALM",
                 SecurityUtil.getServerPrincipal("hdfs/_HOST@REALM", (String)null));
    assertEquals("hdfs/" + local + "@REALM",
                 SecurityUtil.getServerPrincipal("hdfs/_HOST@REALM", "0.0.0.0"));
  }
  
  @Test
  public void testStartsWithIncorrectSettings() throws IOException {
    Configuration conf = new Configuration();
    conf.set(
        org.apache.hadoop.fs.CommonConfigurationKeys.HADOOP_SECURITY_AUTHENTICATION,
        "kerberos");
    String keyTabKey="key";
    conf.set(keyTabKey, "");
    UserGroupInformation.setConfiguration(conf);
    boolean gotException = false;
    try {
      SecurityUtil.login(conf, keyTabKey, "", "");
    } catch (IOException e) {
      // expected
      gotException=true;
    }
    assertTrue("Exception for empty keytabfile name was expected", gotException);
  }
  
  @Test
  public void testGetHostFromPrincipal() {
    assertEquals("host", 
        SecurityUtil.getHostFromPrincipal("service/host@realm"));
    assertEquals(null,
        SecurityUtil.getHostFromPrincipal("service@realm"));
  }

  @Test
  public void testBuildDTServiceName() {
    assertEquals("127.0.0.1:123",
        SecurityUtil.buildDTServiceName(URI.create("test://LocalHost"), 123)
    );
    assertEquals("127.0.0.1:123",
        SecurityUtil.buildDTServiceName(URI.create("test://LocalHost:123"), 456)
    );
    assertEquals("127.0.0.1:123",
        SecurityUtil.buildDTServiceName(URI.create("test://127.0.0.1"), 123)
    );
    assertEquals("127.0.0.1:123",
        SecurityUtil.buildDTServiceName(URI.create("test://127.0.0.1:123"), 456)
    );
  }
  
  @Test
  public void testBuildTokenServiceSockAddr() {
    assertEquals("127.0.0.1:123",
        SecurityUtil.buildTokenService(new InetSocketAddress("LocalHost", 123)).toString()
    );
    assertEquals("127.0.0.1:123",
        SecurityUtil.buildTokenService(new InetSocketAddress("127.0.0.1", 123)).toString()
    );
    // what goes in, comes out
    assertEquals("127.0.0.1:123",
        SecurityUtil.buildTokenService(NetUtils.createSocketAddr("127.0.0.1", 123)).toString()
    );
  }

  @Test
  public void testGoodHostsAndPorts() {
    InetSocketAddress compare = NetUtils.createSocketAddrForHost("localhost", 123);
    runGoodCases(compare, "localhost", 123);
    runGoodCases(compare, "localhost:", 123);
    runGoodCases(compare, "localhost:123", 456);
  }
  
  void runGoodCases(InetSocketAddress addr, String host, int port) {
    assertEquals(addr, NetUtils.createSocketAddr(host, port));
    assertEquals(addr, NetUtils.createSocketAddr("hdfs://"+host, port));
    assertEquals(addr, NetUtils.createSocketAddr("hdfs://"+host+"/path", port));
  }
  
  @Test
  public void testBadHostsAndPorts() {
    runBadCases("", true);
    runBadCases(":", false);
    runBadCases("hdfs/", false);
    runBadCases("hdfs:/", false);
    runBadCases("hdfs://", true);
  }
  
  void runBadCases(String prefix, boolean validIfPosPort) {
    runBadPortPermutes(prefix, false);
    runBadPortPermutes(prefix+"*", false);
    runBadPortPermutes(prefix+"localhost", validIfPosPort);
    runBadPortPermutes(prefix+"localhost:-1", false);
    runBadPortPermutes(prefix+"localhost:-123", false);
    runBadPortPermutes(prefix+"localhost:xyz", false);
    runBadPortPermutes(prefix+"localhost/xyz", validIfPosPort);
    runBadPortPermutes(prefix+"localhost/:123", validIfPosPort);
    runBadPortPermutes(prefix+":123", false);
    runBadPortPermutes(prefix+":xyz", false);
  }

  void runBadPortPermutes(String arg, boolean validIfPosPort) {
    int ports[] = { -123, -1, 123 };
    boolean bad = false;
    try {
      NetUtils.createSocketAddr(arg);
    } catch (IllegalArgumentException e) {
      bad = true;
    } finally {
      assertTrue("should be bad: '"+arg+"'", bad);
    }
    for (int port : ports) {
      if (validIfPosPort && port > 0) continue;
      
      bad = false;
      try {
        NetUtils.createSocketAddr(arg, port);
      } catch (IllegalArgumentException e) {
        bad = true;
      } finally {
        assertTrue("should be bad: '"+arg+"' (default port:"+port+")", bad);
      }
    }
  }

  // check that the socket addr has:
  // 1) the InetSocketAddress has the correct hostname, ie. exact host/ip given
  // 2) the address is resolved, ie. has an ip
  // 3,4) the socket's InetAddress has the same hostname, and the correct ip
  // 5) the port is correct
  private void
  verifyValues(InetSocketAddress addr, String host, String ip, int port) {
    assertTrue(!addr.isUnresolved());
    // don't know what the standard resolver will return for hostname.
    // should be host for host; host or ip for ip is ambiguous
    if (!SecurityUtil.useIpForTokenService) {
      assertEquals(host, addr.getHostName());
      assertEquals(host, addr.getAddress().getHostName());
    }
    assertEquals(ip, addr.getAddress().getHostAddress());
    assertEquals(port, addr.getPort());    
  }

  // check:
  // 1) buildTokenService honors use_ip setting
  // 2) setTokenService & getService works
  // 3) getTokenServiceAddr decodes to the identical socket addr
  private void
  verifyTokenService(InetSocketAddress addr, String host, String ip, int port, boolean useIp) {
    //LOG.info("address:"+addr+" host:"+host+" ip:"+ip+" port:"+port);

    SecurityUtil.setTokenServiceUseIp(useIp);
    String serviceHost = useIp ? ip : host.toLowerCase();
    
    Token token = new Token();
    Text service = new Text(serviceHost+":"+port);
    
    assertEquals(service, SecurityUtil.buildTokenService(addr));
    SecurityUtil.setTokenService(token, addr);
    assertEquals(service, token.getService());
    
    InetSocketAddress serviceAddr = SecurityUtil.getTokenServiceAddr(token);
    assertNotNull(serviceAddr);
    verifyValues(serviceAddr, serviceHost, ip, port);
  }

  // check:
  // 1) socket addr is created with fields set as expected
  // 2) token service with ips
  // 3) token service with the given host or ip
  private void
  verifyAddress(InetSocketAddress addr, String host, String ip, int port) {
    verifyValues(addr, host, ip, port);
    //LOG.info("test that token service uses ip");
    verifyTokenService(addr, host, ip, port, true);    
    //LOG.info("test that token service uses host");
    verifyTokenService(addr, host, ip, port, false);
  }

  // check:
  // 1-4) combinations of host and port
  // this will construct a socket addr, verify all the fields, build the
  // service to verify the use_ip setting is honored, set the token service
  // based on addr and verify the token service is set correctly, decode
  // the token service and ensure all the fields of the decoded addr match
  private void verifyServiceAddr(String host, String ip) {
    InetSocketAddress addr;
    int port = 123;

    // test host, port tuple
    //LOG.info("test tuple ("+host+","+port+")");
    addr = NetUtils.createSocketAddrForHost(host, port);
    verifyAddress(addr, host, ip, port);

    // test authority with no default port
    //LOG.info("test authority '"+host+":"+port+"'");
    addr = NetUtils.createSocketAddr(host+":"+port);
    verifyAddress(addr, host, ip, port);

    // test authority with a default port, make sure default isn't used
    //LOG.info("test authority '"+host+":"+port+"' with ignored default port");
    addr = NetUtils.createSocketAddr(host+":"+port, port+1);
    verifyAddress(addr, host, ip, port);

    // test host-only authority, using port as default port
    //LOG.info("test host:"+host+" port:"+port);
    addr = NetUtils.createSocketAddr(host, port);
    verifyAddress(addr, host, ip, port);
  }

  @Test
  public void testSocketAddrWithName() {
    String staticHost = "my";
    NetUtils.addStaticResolution(staticHost, "localhost");
    verifyServiceAddr("LocalHost", "127.0.0.1");
  }

  @Test
  public void testSocketAddrWithIP() {
    verifyServiceAddr("127.0.0.1", "127.0.0.1");
  }

  @Test
  public void testSocketAddrWithNameToStaticName() {
    String staticHost = "host1";
    NetUtils.addStaticResolution(staticHost, "localhost");
    verifyServiceAddr(staticHost, "127.0.0.1");
  }

  @Test
  public void testSocketAddrWithNameToStaticIP() {
    String staticHost = "host3";
    NetUtils.addStaticResolution(staticHost, "255.255.255.255");
    verifyServiceAddr(staticHost, "255.255.255.255");
  }

  // this is a bizarre case, but it's if a test tries to remap an ip address
  @Test
  public void testSocketAddrWithIPToStaticIP() {
    String staticHost = "1.2.3.4";
    NetUtils.addStaticResolution(staticHost, "255.255.255.255");
    verifyServiceAddr(staticHost, "255.255.255.255");
  }
}
