001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.hadoop.security.alias; 020 021import org.apache.hadoop.classification.InterfaceAudience; 022import org.apache.hadoop.conf.Configuration; 023import org.apache.hadoop.fs.FSDataOutputStream; 024import org.apache.hadoop.fs.FileStatus; 025import org.apache.hadoop.fs.FileSystem; 026import org.apache.hadoop.fs.permission.FsPermission; 027 028import java.io.IOException; 029import java.io.InputStream; 030import java.io.OutputStream; 031import java.net.URI; 032 033/** 034 * CredentialProvider based on Java's KeyStore file format. The file may be 035 * stored in any Hadoop FileSystem using the following name mangling: 036 * jceks://hdfs@nn1.example.com/my/creds.jceks -> 037 * hdfs://nn1.example.com/my/creds.jceks jceks://file/home/larry/creds.jceks -> 038 * file:///home/larry/creds.jceks 039 */ 040@InterfaceAudience.Private 041public class JavaKeyStoreProvider extends AbstractJavaKeyStoreProvider { 042 public static final String SCHEME_NAME = "jceks"; 043 044 private FileSystem fs; 045 private FsPermission permissions; 046 047 private JavaKeyStoreProvider(URI uri, Configuration conf) 048 throws IOException { 049 super(uri, conf); 050 } 051 052 @Override 053 protected String getSchemeName() { 054 return SCHEME_NAME; 055 } 056 057 @Override 058 protected OutputStream getOutputStreamForKeystore() throws IOException { 059 FSDataOutputStream out = FileSystem.create(fs, getPath(), permissions); 060 return out; 061 } 062 063 @Override 064 protected boolean keystoreExists() throws IOException { 065 return fs.exists(getPath()); 066 } 067 068 @Override 069 protected InputStream getInputStreamForFile() throws IOException { 070 return fs.open(getPath()); 071 } 072 073 @Override 074 protected void createPermissions(String perms) { 075 permissions = new FsPermission(perms); 076 } 077 078 @Override 079 protected void stashOriginalFilePermissions() throws IOException { 080 // save off permissions in case we need to 081 // rewrite the keystore in flush() 082 FileStatus s = fs.getFileStatus(getPath()); 083 permissions = s.getPermission(); 084 } 085 086 protected void initFileSystem(URI uri) 087 throws IOException { 088 super.initFileSystem(uri); 089 fs = getPath().getFileSystem(getConf()); 090 } 091 092 /** 093 * The factory to create JksProviders, which is used by the ServiceLoader. 094 */ 095 public static class Factory extends CredentialProviderFactory { 096 @Override 097 public CredentialProvider createProvider(URI providerName, 098 Configuration conf) throws IOException { 099 if (SCHEME_NAME.equals(providerName.getScheme())) { 100 return new JavaKeyStoreProvider(providerName, conf); 101 } 102 return null; 103 } 104 } 105}