mirror of
https://github.com/livingcomputermuseum/IFS.git
synced 2026-04-06 13:31:15 +00:00
Added authorization to CopyDisk, minor BSP cleanup.
This commit is contained in:
@@ -508,6 +508,20 @@ namespace IFS.BSP
|
||||
Log.Write(LogType.Verbose, LogComponent.BSP, "ACK sent.");
|
||||
}
|
||||
|
||||
public void RecvError(PUP errorPup)
|
||||
{
|
||||
// For now, just log this.
|
||||
Log.Write(LogType.Error, LogComponent.BSP,
|
||||
"Error from client, unhandled.");
|
||||
}
|
||||
|
||||
public void RecvInterrupt(PUP interruptPup)
|
||||
{
|
||||
// For now, just log this. No IFS protcols yet implemented require use of interrupts.
|
||||
Log.Write(LogType.Error, LogComponent.BSP,
|
||||
"Interrupt from client, unhandled.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a PUP. Will block if client is unable to receive data. If timeouts expire, channel will be shut down.
|
||||
/// </summary>
|
||||
|
||||
@@ -17,17 +17,6 @@ namespace IFS.BSP
|
||||
public ushort BytesSent;
|
||||
}
|
||||
|
||||
public abstract class BSPProtocol : PUPProtocolBase
|
||||
{
|
||||
public abstract void InitializeServerForChannel(BSPChannel channel);
|
||||
}
|
||||
|
||||
public enum BSPState
|
||||
{
|
||||
Unconnected,
|
||||
Connected
|
||||
}
|
||||
|
||||
public delegate void WorkerExitDelegate(BSPWorkerBase destroyed);
|
||||
|
||||
public abstract class BSPWorkerBase
|
||||
@@ -169,6 +158,18 @@ namespace IFS.BSP
|
||||
}
|
||||
break;
|
||||
|
||||
case PupType.Error:
|
||||
{
|
||||
channel.RecvError(p);
|
||||
}
|
||||
break;
|
||||
|
||||
case PupType.Interrupt:
|
||||
{
|
||||
channel.RecvInterrupt(p);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException(String.Format("Unhandled BSP PUP type {0}.", p.Type));
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
# Debug settings
|
||||
|
||||
LogTypes = Normal
|
||||
LogTypes = All
|
||||
LogComponents = All
|
||||
|
||||
# Normal configuration
|
||||
|
||||
@@ -34,6 +34,10 @@ namespace IFS.CopyDisk
|
||||
UnitWriteProtected = 2,
|
||||
OverwriteNotAllowed = 3,
|
||||
UnknownCommand = 4,
|
||||
IllegalUserName = 16,
|
||||
IllegalOrIncorrectPassword = 17,
|
||||
IllegalConnectName = 18,
|
||||
IllegalConnectPassword = 19,
|
||||
}
|
||||
|
||||
struct VersionYesNoBlock
|
||||
@@ -280,21 +284,30 @@ namespace IFS.CopyDisk
|
||||
{
|
||||
LoginBlock login = (LoginBlock)Serializer.Deserialize(data, typeof(LoginBlock));
|
||||
|
||||
Log.Write(LogType.Verbose, LogComponent.CopyDisk, "Login is for user {0}, password {1}, connection {2}, connection password {3}.",
|
||||
Log.Write(LogType.Verbose, LogComponent.CopyDisk, "Login is for user '{0}', password '{1}', connection '{2}', connection password '{3}'.",
|
||||
login.UserName,
|
||||
login.UserPassword,
|
||||
login.ConnName,
|
||||
login.ConnPassword);
|
||||
|
||||
//
|
||||
// TODO: for now we allow anyone in with any username and password, this needs to be fixed once
|
||||
// an authentication mechanism is set up.
|
||||
//
|
||||
_userToken = AuthenticateUser(login.UserName.ToString(), login.UserPassword.ToString());
|
||||
|
||||
// Send a "Yes" response back.
|
||||
//
|
||||
VersionYesNoBlock yes = new VersionYesNoBlock(CopyDiskBlock.Yes, 0, "Come on in, the water's fine.");
|
||||
_channel.Send(Serializer.Serialize(yes));
|
||||
if (_userToken != null)
|
||||
{
|
||||
//
|
||||
// Send a "Yes" response back.
|
||||
//
|
||||
VersionYesNoBlock yes = new VersionYesNoBlock(CopyDiskBlock.Yes, 0, "Come on in, the water's fine.");
|
||||
_channel.Send(Serializer.Serialize(yes));
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Send a "No" response back indicating the login failure.
|
||||
//
|
||||
VersionYesNoBlock no = new VersionYesNoBlock(CopyDiskBlock.No, (ushort)NoCode.IllegalOrIncorrectPassword, "Invalid username or password.");
|
||||
_channel.Send(Serializer.Serialize(no), true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -408,6 +421,17 @@ namespace IFS.CopyDisk
|
||||
_startAddress = _pack.DiskAddressToVirtualAddress(transferParameters.StartAddress);
|
||||
_endAddress = _pack.DiskAddressToVirtualAddress(transferParameters.EndAddress);
|
||||
|
||||
// Validate that the user is allowed to store.
|
||||
if (blockType == CopyDiskBlock.StoreDisk)
|
||||
{
|
||||
if (_userToken.Privileges != IFSPrivileges.ReadWrite)
|
||||
{
|
||||
VersionYesNoBlock no = new VersionYesNoBlock(CopyDiskBlock.No, (ushort)NoCode.UnitWriteProtected, "You do not have permission to store disk images.");
|
||||
_channel.Send(Serializer.Serialize(no));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Log.Write(LogType.Verbose, LogComponent.CopyDisk, "Transfer is from block {0} to block {1}", transferParameters.StartAddress, transferParameters.EndAddress);
|
||||
|
||||
// Validate start/end parameters
|
||||
@@ -419,7 +443,7 @@ namespace IFS.CopyDisk
|
||||
_channel.Send(Serializer.Serialize(no));
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
// We're OK. Save the parameters and send a Yes response.
|
||||
VersionYesNoBlock yes = new VersionYesNoBlock(CopyDiskBlock.Yes, 0, "You are cleared for launch.");
|
||||
_channel.Send(Serializer.Serialize(yes));
|
||||
@@ -564,6 +588,22 @@ namespace IFS.CopyDisk
|
||||
}
|
||||
}
|
||||
|
||||
private UserToken AuthenticateUser(string userName, string password)
|
||||
{
|
||||
//
|
||||
// If no username is specified then we default to the guest account.
|
||||
//
|
||||
if (string.IsNullOrEmpty(userName))
|
||||
{
|
||||
return UserToken.Guest;
|
||||
}
|
||||
|
||||
UserToken user = Authentication.Authenticate(userName, password);
|
||||
|
||||
return user;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a relative path to the directory that holds the disk images.
|
||||
/// </summary>
|
||||
@@ -577,6 +617,9 @@ namespace IFS.CopyDisk
|
||||
private Thread _workerThread;
|
||||
private bool _running;
|
||||
|
||||
// The user token for this transaction. We assume guest access by default.
|
||||
private UserToken _userToken = UserToken.Guest;
|
||||
|
||||
// The pack being read / stored by this server
|
||||
private DiabloPack _pack = null;
|
||||
|
||||
|
||||
@@ -839,6 +839,12 @@ namespace IFS.FTP
|
||||
/// <returns></returns>
|
||||
private bool IsUserDirectory(UserToken userToken, string fullPath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(userToken.HomeDirectory))
|
||||
{
|
||||
// No home directory, so by default this cannot be the user's home directory.
|
||||
return false;
|
||||
}
|
||||
|
||||
string userDirPath = Path.Combine(Configuration.FTPRoot, userToken.HomeDirectory);
|
||||
return fullPath.StartsWith(userDirPath, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user