001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.commons.io.res.type.smb; 020 021import java.io.IOException; 022import java.net.MalformedURLException; 023import java.nio.charset.Charset; 024import java.util.Map; 025import java.util.regex.Pattern; 026 027import jcifs.smb.NtlmPasswordAuthentication; 028import jcifs.smb.SmbFile; 029import lucee.commons.io.res.Resource; 030import lucee.commons.io.res.ResourceProvider; 031import lucee.commons.io.res.Resources; 032import lucee.commons.io.res.util.ResourceLockImpl; 033import lucee.commons.lang.StringUtil; 034 035import org.apache.commons.codec.binary.Base32; 036 037public class SMBResourceProvider implements ResourceProvider{ 038 039 private String scheme="smb"; 040 private Map<String,String> args; 041 private final static String ENCRYPTED_PREFIX = "$smb-enc$"; 042 private final static Charset UTF8 = Charset.forName("UTF-8"); 043 private final ResourceLockImpl lock=new ResourceLockImpl(10000,false); 044 private final static Base32 Base32DecEnc = new Base32(); 045 @Override 046 public ResourceProvider init(String scheme, Map arguments) { 047 _setProperties(arguments); 048 049 if(!StringUtil.isEmpty(scheme))this.scheme=scheme; 050 this.args = arguments; 051 return this; 052 } 053 054 private void _setProperties(Map arguments) { 055 056 String resolveOrder = (String)arguments.get("resolveOrder"); 057 if (resolveOrder == null) resolveOrder = "DNS"; 058 059 String dfsDisabled = (String)arguments.get("smb.client.dfs.disabled"); 060 if (dfsDisabled == null) dfsDisabled = "true"; 061 System.setProperty("jcifs.resolveOrder", resolveOrder); 062 System.setProperty("jcifs.smb.client.dfs.disabled", dfsDisabled); 063 064 065 } 066 067 public Resource getResource(String path, NtlmPasswordAuthentication auth) { 068 return new SMBResource( this, path, auth ); 069 } 070 071 @Override 072 public Resource getResource(String path) { 073 return new SMBResource( this, path ); 074 } 075 076 @Override 077 public String getScheme() { 078 return scheme; 079 } 080 081 @Override 082 public Map<String, String> getArguments() { 083 return args; 084 } 085 086 @Override 087 public void setResources(Resources resources) { 088 // TODO Not sure what this does 089 } 090 091 @Override 092 public void unlock(Resource res) { 093 lock.unlock(res); 094 } 095 096 @Override 097 public void lock(Resource res) throws IOException { 098 lock.lock(res); 099 } 100 101 @Override 102 public void read(Resource res) throws IOException { 103 lock.read(res); 104 } 105 106 @Override 107 public boolean isCaseSensitive() { 108 return false; 109 } 110 111 @Override 112 public boolean isModeSupported() { 113 return false; 114 } 115 116 @Override 117 public boolean isAttributesSupported() { 118 return false; 119 } 120 121 public SmbFile getFile(String path, NtlmPasswordAuthentication auth) { 122 try { 123 return new SmbFile(path,auth); 124 } 125 catch (MalformedURLException e) { 126 return null; //null means it is a bad SMBFile 127 } 128 } 129 130 public static boolean isEncryptedUserInfo(String userInfo) { 131 return userInfo.startsWith(ENCRYPTED_PREFIX); 132 } 133 134 public static String unencryptUserInfo(String userInfo) { 135 if(!isEncryptedUserInfo(userInfo)) return userInfo; 136 String encrypted = userInfo.replaceAll(Pattern.quote(ENCRYPTED_PREFIX),""); 137 byte[] unencryptedBytes = Base32DecEnc.decode(encrypted.toUpperCase()); 138 return new String(unencryptedBytes, UTF8); 139 140 } 141 142 public static String encryptUserInfo(String userInfo) { 143 byte[] bytes = Base32DecEnc.encode( userInfo.getBytes(UTF8) ); 144 return ENCRYPTED_PREFIX.concat(new String(bytes, UTF8)); 145 } 146}