/// <summary> Our extension of Start Channel (see ChannelControlListener) /// does a lot of things. It begins the authentication, and in /// some cases (if the user has packed data in <blob> form on /// the startChannel request) can actually finish the anonymous /// authentication. /// </summary> public virtual void startChannel(Channel channel, System.String encoding, System.String data) { log.debug("SASLAnonymousProfile.startChannel"); clearCredential(channel.Session, this); Session t = channel.Session; try { AnonymousAuthenticator auth = new AnonymousAuthenticator(this); auth.started(channel); } catch (System.Exception x) { //UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Throwable.getMessage' may return a different value. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1043"' channel.Session.terminate(x.Message); return ; } }
/// <summary> /// The entry point of the program. /// </summary> /// <param name="args">Argumentss entered in the shell/param>. private static void Main(string[] args) { Console.WriteLine("FTP Server by Zhaobang China"); Console.WriteLine("Server version: {0}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version); Console.WriteLine("Library version: {0}", System.Reflection.Assembly.GetAssembly(typeof(FtpServer)).GetName().Version); Console.WriteLine("This is an open source project. Project site: https://github.com/ZhaobangChina/FtpServer/tree/master/Server"); Console.WriteLine(); RunConfig config = RunConfig.Default; XmlSerializer serializer = new XmlSerializer(typeof(RunConfig)); FileInfo configFileInfo = new FileInfo(Path.Combine(Environment.CurrentDirectory, "RunConfig.xml")); List <FtpServer> servers = new List <FtpServer>(); if (configFileInfo.Exists) { using (Stream configFileStream = configFileInfo.OpenRead()) { config = serializer.Deserialize(configFileStream) as RunConfig; } } else { using (Stream configFileStream = configFileInfo.OpenWrite()) { Console.WriteLine("Creating default config file at {0}", configFileInfo.FullName); serializer.Serialize(configFileStream, config); Console.WriteLine("Default config file created"); } } X509Certificate certificate = null; try { if (!string.IsNullOrEmpty(config.CertificatePath)) { certificate = new X509Certificate(config.CertificatePath, config.CertificatePassword); config.CertificatePassword = null; } var cancelSource = new CancellationTokenSource(); var runResults = config.EndPoints.Select( ep => { var fileProviderFactory = new SimpleFileProviderFactory(config.BaseDirectory); var dataConnectionFactory = certificate == null ? new LocalDataConnectionFactory() : (IDataConnectionFactory) new SslLocalDataConnectionFactory(certificate); var authenticator = new AnonymousAuthenticator(); var controlConnectionSslFactory = certificate == null ? null : new ControlConnectionSslFactory(certificate); var server = new FtpServer(ep, fileProviderFactory, dataConnectionFactory, authenticator, controlConnectionSslFactory); servers.Add(server); return(server.RunAsync(cancelSource.Token) .ContinueWith(result => { if (result.Exception != null) { Console.WriteLine($"Server at {ep} has stopped because of: \n{result.Exception.Message}\n"); } else { Console.WriteLine($"Server at {ep} has stopped successfully."); } })); }) .ToArray(); Console.WriteLine("FTP server has been started."); Console.WriteLine("Config file: \n\t{0}", configFileInfo.FullName); Console.WriteLine("Root dir: \n\t{0}", config.BaseDirectory); Console.WriteLine( "End points:\n\t{0}", string.Join("\n\t", config.EndPoints.Select(ep => ep.ToString()))); Console.WriteLine("Use command \"quit\" to stop FTP server."); Console.WriteLine("Use command \"users\" to list connected users."); while (true) { var command = Console.ReadLine(); if (command.ToUpper(CultureInfo.InvariantCulture) == "QUIT") { cancelSource.Cancel(); Console.WriteLine("Stopped accepting new connections. Waiting until all clients quit."); Task.WaitAll(runResults); Console.WriteLine("Quited."); return; } else if (command.ToUpper(CultureInfo.InvariantCulture) == "USERS") { Console.WriteLine("Connected users:"); foreach (var server in servers) { lock (server.Tracer.ConnectedUsersSyncRoot) { foreach (var user in server.Tracer.ConnectedUsersView) { Console.WriteLine(user.ToString()); } } } } } } finally { certificate.Dispose(); } }
/// <summary> Method authencitateSASLAnonymous is an Initiator routine designed /// to allow a peer to authenticate to another one. /// /// </summary> /// <param name="session">Session the current session /// </param> /// <param name="id">The identity of the peer withing to authenticate /// /// @throws SASLException if any failure occurs. /// </param> public static Session AuthenticateSASLAnonymous(Session session, System.String id) { if ((System.Object) id == null) { id = ANONYMOUS; } clearCredential(session, null); AnonymousAuthenticator auth = new AnonymousAuthenticator(Instance); Channel ch = session.startChannel(SASLAnonymousProfile.uri, auth); auth.started(ch); auth.sendIdentity(id); lock (auth) { try { System.Threading.Monitor.Wait(auth); //FIX for bug 469725, if authentication fails no local Cred is //set and a AuthenticationFailureException is thrown if (ch.Session.getLocalCredential() == null) { throw new AuthenticationFailureException("Could not authenticate with SASL/ANON"); } return ch.Session; } catch (System.Threading.ThreadInterruptedException x) { } } return null; }