Last active
January 3, 2024 16:48
-
-
Save dovidkopel/9eca457e670fb9272ad7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.alfresco.jlan.server.SrvSession; | |
import org.alfresco.jlan.server.core.DeviceContext; | |
import org.alfresco.jlan.server.filesys.FileExistsException; | |
import org.alfresco.jlan.server.filesys.FileName; | |
import org.alfresco.jlan.server.filesys.FileOpenParams; | |
import org.alfresco.jlan.server.filesys.NetworkFile; | |
import org.alfresco.jlan.server.filesys.TreeConnection; | |
import org.alfresco.jlan.smb.server.disk.JavaFileDiskDriver; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.stereotype.Component; | |
import java.io.File; | |
import java.io.IOException; | |
/** | |
* Created by dkopel on 3/13/16. | |
*/ | |
@Component | |
public class InMemoryFileDriver extends JavaFileDiskDriver { | |
private Logger logger = LoggerFactory.getLogger(getClass()); | |
private NetworkFile f; | |
@Override | |
public NetworkFile createFile(SrvSession sess, TreeConnection tree, FileOpenParams params) throws IOException { | |
DeviceContext ctx = tree.getContext(); | |
String fname = FileName.buildPath(ctx.getDeviceName(), params.getPath(), (String)null, File.separatorChar); | |
File file = new File(fname); | |
logger.info("User {} created a new file called {}.", sess.getClientInformation().getUserName(), fname); | |
if(file.exists()) { | |
throw new FileExistsException(); | |
} else { | |
InMemoryNetworkFile netFile = new InMemoryNetworkFile(fname); | |
netFile.setGrantedAccess(2); | |
netFile.setAllowedAccess(2); | |
netFile.setFullName(params.getPath()); | |
return netFile; | |
} | |
} | |
@Override | |
public int writeFile(SrvSession sess, TreeConnection tree, NetworkFile file, byte[] buf, int bufoff, int siz, long fileoff) throws IOException { | |
logger.info("Write request to file {} with data {} {}.", file.getFullName(), siz); | |
return super.writeFile(sess, tree, file, buf, bufoff, siz, fileoff); | |
} | |
@Override | |
public void closeFile(SrvSession sess, TreeConnection tree, NetworkFile file) throws IOException { | |
super.closeFile(sess, tree, file); | |
logger.info("Close file {}.", file.getFullName(), sess.getClientInformation().getUserName()); | |
// Over here if we had a write we can now transfer the contents of the file into our system! | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.alfresco.jlan.server.filesys.NetworkFile; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.util.concurrent.atomic.AtomicBoolean; | |
/** | |
* @author Created by dkopel on 3/15/16. | |
*/ | |
public class InMemoryNetworkFile extends NetworkFile { | |
private ByteArrayOutputStream out = new ByteArrayOutputStream(); | |
private byte[] data; | |
private AtomicBoolean opened = new AtomicBoolean(false); | |
private Logger logger = LoggerFactory.getLogger(getClass()); | |
public InMemoryNetworkFile(int fid) { | |
super(fid); | |
} | |
public InMemoryNetworkFile(int fid, int did) { | |
super(fid, did); | |
} | |
public InMemoryNetworkFile(int fid, int stid, int did) { | |
super(fid, stid, did); | |
} | |
public InMemoryNetworkFile(String name) { | |
super(name); | |
} | |
@Override | |
public void openFile(boolean b) throws IOException { | |
opened.set(b); | |
} | |
@Override | |
public int readFile(byte[] bytes, int i, int i1, long l) throws IOException { | |
return 0; | |
} | |
@Override | |
public void writeFile(byte[] bytes, int len, int pos, long offset) throws IOException { | |
logger.debug("Bytes Size: {}, Length: {}, Position: {}, Offset: {}", bytes.length, len, pos, offset); | |
out.write(bytes, pos, len); | |
logger.debug("Data is now {} bytes", out.size()); | |
} | |
@Override | |
public long seekFile(long l, int i) throws IOException { | |
return 0; | |
} | |
@Override | |
public void flushFile() throws IOException { | |
logger.info("Flushed!"); | |
} | |
@Override | |
public void truncateFile(long l) throws IOException { | |
out.reset(); | |
} | |
@Override | |
public void closeFile() throws IOException { | |
opened.set(false); | |
out.close(); | |
data = out.toByteArray(); | |
} | |
public byte[] getData() { | |
return data; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.alfresco.jlan.debug.DebugConfigSection; | |
import org.alfresco.jlan.netbios.server.NetBIOSNameServer; | |
import org.alfresco.jlan.server.NetworkServer; | |
import org.alfresco.jlan.server.auth.EnterpriseCifsAuthenticator; | |
import org.alfresco.jlan.server.auth.acl.DefaultAccessControlManager; | |
import org.alfresco.jlan.server.config.CoreServerConfigSection; | |
import org.alfresco.jlan.server.config.GlobalConfigSection; | |
import org.alfresco.jlan.server.config.InvalidConfigurationException; | |
import org.alfresco.jlan.server.config.SecurityConfigSection; | |
import org.alfresco.jlan.server.config.ServerConfiguration; | |
import org.alfresco.jlan.server.core.DeviceContextException; | |
import org.alfresco.jlan.server.filesys.DiskDeviceContext; | |
import org.alfresco.jlan.server.filesys.DiskInterface; | |
import org.alfresco.jlan.server.filesys.DiskSharedDevice; | |
import org.alfresco.jlan.server.filesys.FilesystemsConfigSection; | |
import org.alfresco.jlan.server.filesys.SrvDiskInfo; | |
import org.alfresco.jlan.smb.server.CIFSConfigSection; | |
import org.alfresco.jlan.smb.server.SMBServer; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.beans.factory.BeanFactory; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.beans.factory.annotation.Value; | |
import org.springframework.context.annotation.Profile; | |
import org.springframework.extensions.config.element.GenericConfigElement; | |
import org.springframework.stereotype.Service; | |
import javax.annotation.PostConstruct; | |
/** | |
* Created by dkopel on 3/13/16. | |
*/ | |
@Service | |
public class SmbService { | |
private BeanFactory beanFactory; | |
private UserAuthenticationService userAuthenticationService; | |
@Value("${smb.hostname}") | |
private String hostname; | |
@Value("${smb.domain}") | |
private String domain; | |
@Value("${smb.share}") | |
private String share; | |
@Value("${smb.broadcastMask}") | |
private String broadcastMask; | |
private Logger LOGGER = LoggerFactory.getLogger(getClass()); | |
@Autowired | |
public SmbService setUserAuthenticationService(UserAuthenticationService userAuthenticationService) { | |
this.userAuthenticationService = userAuthenticationService; | |
return this; | |
} | |
@Autowired | |
public SmbService setBeanFactory(BeanFactory beanFactory) { | |
this.beanFactory = beanFactory; | |
return this; | |
} | |
@PostConstruct | |
public void init() { | |
try { | |
ServerConfiguration cfg = new DarkPointServerConfig(); | |
NetBIOSNameServer netBIOSNameServer = new NetBIOSNameServer(cfg); | |
cfg.addServer(netBIOSNameServer); | |
SMBServer smbServer = new SMBServer(cfg); | |
cfg.addServer(smbServer); | |
for (int i = 0; i < cfg.numberOfServers(); i++) { | |
NetworkServer server = cfg.getServer(i); | |
server.startServer(); | |
} | |
} catch (Exception e) { | |
LOGGER.error("Something went terribly wrong with the samba server!"); | |
e.printStackTrace(); | |
} | |
} | |
class ServerConfig extends ServerConfiguration { | |
private Logger logger = LoggerFactory.getLogger(getClass()); | |
private static final int DefaultThreadPoolInit = 1; | |
private static final int DefaultThreadPoolMax = 1; | |
private final int[] DefaultMemoryPoolBufSizes = { 256, 4096, 16384, 66000 }; | |
private final int[] DefaultMemoryPoolInitAlloc = { 20, 20, 5, 5 }; | |
private final int[] DefaultMemoryPoolMaxAlloc = { 100, 50, 50, 50 }; | |
public ServerConfig() throws InvalidConfigurationException, DeviceContextException { | |
super(hostname); | |
setServerName(hostname); | |
// DEBUG | |
DebugConfigSection debugConfig = new DebugConfigSection(this); | |
final GenericConfigElement debugConfigElement = new GenericConfigElement("output"); | |
final GenericConfigElement logLevelConfigElement = new GenericConfigElement("logLevel"); | |
logLevelConfigElement.setValue("Info"); | |
debugConfig.setDebug("org.alfresco.jlan.debug.ConsoleDebug", debugConfigElement); | |
// CORE | |
CoreServerConfigSection coreConfig = new CoreServerConfigSection(this); | |
coreConfig.setMemoryPool( DefaultMemoryPoolBufSizes, DefaultMemoryPoolInitAlloc, DefaultMemoryPoolMaxAlloc); | |
coreConfig.setThreadPool(DefaultThreadPoolInit, DefaultThreadPoolMax); | |
coreConfig.getThreadPool().setDebug(false); | |
// GLOBAL | |
GlobalConfigSection globalConfig = new GlobalConfigSection(this); | |
// SECURITY | |
final SecurityConfigSection secConfig = new SecurityConfigSection(this); | |
secConfig.setUsersInterface( | |
"connector.smb.UsersInterface", | |
new GenericConfigElement("") | |
); | |
this.addConfigSection(secConfig); | |
DefaultAccessControlManager accessControlManager = new DefaultAccessControlManager(); | |
accessControlManager.setDebug(false); | |
// SHARES | |
FilesystemsConfigSection filesysConfig = new FilesystemsConfigSection(this); | |
DiskInterface diskInterface = beanFactory.getBean(InMemoryFileDriver.class); | |
final GenericConfigElement driverConfig = new GenericConfigElement("driver"); | |
final GenericConfigElement localPathConfig = new GenericConfigElement("LocalPath"); | |
localPathConfig.setValue("/tmp"); | |
driverConfig.addChild(localPathConfig); | |
DiskDeviceContext diskDeviceContext = (DiskDeviceContext) diskInterface.createContext(share, driverConfig); | |
diskDeviceContext.setShareName(share); | |
diskDeviceContext.setConfigurationParameters(driverConfig); | |
diskDeviceContext.enableChangeHandler(false); | |
diskDeviceContext.setDiskInformation(new SrvDiskInfo(2560000, 64, 512, 2304000));// Default to a 80Gb sized disk with 90% free space | |
DiskSharedDevice diskDev = new DiskSharedDevice(share, diskInterface, diskDeviceContext); | |
diskDev.setConfiguration(this); | |
diskDev.setAccessControlList(secConfig.getGlobalAccessControls()); | |
diskDeviceContext.startFilesystem(diskDev); | |
filesysConfig.addShare(diskDev); | |
// SMB | |
CIFSConfigSection cifsConfig = new CIFSConfigSection(this); | |
if(broadcastMask != null && broadcastMask.length() > 0) { | |
cifsConfig.setBroadcastMask(broadcastMask); | |
} | |
if(domain != null && domain.length() > 0) { | |
cifsConfig.setDomainName(domain); | |
} | |
cifsConfig.setServerName(hostname); | |
cifsConfig.setHostAnnounceInterval(5); | |
cifsConfig.setHostAnnouncer(true); | |
cifsConfig.setWin32NetBIOS(true); | |
cifsConfig.setWin32HostAnnounceInterval(5); | |
cifsConfig.setTcpipSMB(true); | |
final EnterpriseCifsAuthenticator authenticator = new EnterpriseCifsAuthenticator(); | |
authenticator.setDebug(true); | |
authenticator.setAllowGuest(false); | |
authenticator.setAccessMode(EnterpriseCifsAuthenticator.NTLM2); | |
authenticator.initialize(this, new GenericConfigElement("authenticator")); | |
cifsConfig.setAuthenticator(authenticator); | |
// For debugging SMB in depth | |
//cifsConfig.setSessionDebugFlags(-1); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.sun.xml.internal.fastinfoset.util.CharArray; | |
import org.springframework.security.core.userdetails.User; | |
import org.springframework.security.core.userdetails.UserDetails; | |
import org.alfresco.jlan.server.auth.UserAccount; | |
import org.alfresco.jlan.server.auth.UsersInterface; | |
import org.alfresco.jlan.server.config.InvalidConfigurationException; | |
import org.alfresco.jlan.server.config.ServerConfiguration; | |
import org.alfresco.jlan.util.HexDump; | |
import org.apache.commons.codec.DecoderException; | |
import org.apache.commons.codec.binary.Hex; | |
import org.bouncycastle.jce.provider.BouncyCastleProvider; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.extensions.config.ConfigElement; | |
import java.security.Security; | |
/** | |
* Created by dkopel on 3/15/16. | |
*/ | |
public class UsersInterface implements UsersInterface { | |
private Logger logger = LoggerFactory.getLogger(getClass()); | |
private UserAuthenticationService userAuthenticationService; | |
public UsersInterface() { | |
Security.addProvider(new BouncyCastleProvider()); | |
userAuthenticationService = BeanAccessor.getBean(UserAuthenticationService.class); | |
} | |
@Override | |
public void initializeUsers(ServerConfiguration serverConfiguration, ConfigElement configElement) throws InvalidConfigurationException { | |
} | |
@Override | |
public UserAccount getUserAccount(String s) { | |
MD4User u = findAccount(s); | |
if(u != null) { | |
logger.info("User exists with the username {}", s); | |
logger.info("MD4 Password {}", HexDump.hexString(u.getPasswordMD4())); | |
UserAccount us = new UserAccount( | |
u.getUsername(), | |
null | |
); | |
try { | |
us.setMD4Password(Hex.decodeHex(u.getPasswordMD4String().toCharArray())); | |
} catch (DecoderException e) { | |
e.printStackTrace(); | |
} | |
return us; | |
} else { | |
logger.info("User does not exist with the username {}", s); | |
return null; | |
} | |
} | |
public MD4User findAccount(String s) { | |
return userAuthenticationService.getUser(s); | |
} | |
interface UserAuthenticationService { | |
boolean authenticate(String username, String password); | |
MD4User getUser(String username); | |
} | |
interface MD4User extends UserDetails { | |
byte[] getPasswordMD4(); | |
String getPasswordMD4String(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment