Пример #1
0
        public static int StartDaemon(ClientInfo clientInfo)
        {
            IOStream stream  = clientInfo.IoStream;
            Options  options = clientInfo.Options;

            options.amDaemon = true;

            stream.IOPrintf("@RSYNCD: " + options.protocolVersion + "\n");
            string line = stream.ReadLine();

            try
            {
                options.remoteProtocol = Int32.Parse(line.Substring(9, 2));
            }
            catch
            {
                options.remoteProtocol = 0;
            }
            bool isValidstring = line.StartsWith("@RSYNCD: ") && line.EndsWith("\n") && options.remoteProtocol > 0;

            if (!isValidstring)
            {
                stream.IOPrintf("@ERROR: protocol startup error\n");
                return(-1);
            }
            if (options.protocolVersion > options.remoteProtocol)
            {
                options.protocolVersion = options.remoteProtocol;
            }
            line = stream.ReadLine();
            if (line.CompareTo("#list\n") == 0)
            {
                ClientServer.SendListing(stream);
                return(-1);
            }

            if (line[0] == '#')
            {
                stream.IOPrintf("@ERROR: Unknown command '" + line.Replace("\n", String.Empty) + "'\n");
                return(-1);
            }

            int i = config.GetNumberModule(line.Replace("\n", String.Empty));

            if (i < 0)
            {
                stream.IOPrintf("@ERROR: Unknown module " + line);
                MainClass.Exit("@ERROR: Unknown module " + line, clientInfo);
            }
            options.doStats  = true;
            options.ModuleId = i;
            ClientServer.RsyncModule(clientInfo, i);
            clientInfo.IoStream.Close();
            return(1);
        }
Пример #2
0
        public void SendExcludeList(IOStream f)
        {
            if (options.listOnly && !options.recurse)
            {
                AddExclude(ref options.excludeList, "/*/*", 0);
            }

            foreach (ExcludeStruct ent in options.excludeList)
            {
                int    l;
                string p;

                if (ent.pattern.Length == 0 || ent.pattern.Length > Options.MAXPATHLEN)
                {
                    continue;
                }
                l = ent.pattern.Length;
                p = ent.pattern;
                if ((ent.matchFlags & Options.MATCHFLG_DIRECTORY) != 0)
                {
                    p += "/\0";
                }

                if ((ent.matchFlags & Options.MATCHFLG_INCLUDE) != 0)
                {
                    f.writeInt(l + 2);
                    f.IOPrintf("+ ");
                }
                else if ((p[0] == '-' || p[0] == '+') && p[1] == ' ')
                {
                    f.writeInt(l + 2);
                    f.IOPrintf("- ");
                }
                else
                {
                    f.writeInt(l);
                }
                f.IOPrintf(p);
            }
            f.writeInt(0);
        }
Пример #3
0
		public void SendExcludeList(IOStream f)
		{						
			if (options.listOnly && !options.recurse)
				AddExclude(ref options.excludeList,"/*/*",0);				

			foreach (ExcludeStruct ent in options.excludeList) 			
			{
				int l;				
				string p;

				if(ent.pattern.Length == 0 || ent.pattern.Length > Options.MAXPATHLEN)
					continue;
				l = ent.pattern.Length;
				p = ent.pattern;				
				if ((ent.matchFlags & Options.MATCHFLG_DIRECTORY) != 0) 
				{
					p += "/\0";					
				}

				if ((ent.matchFlags & Options.MATCHFLG_INCLUDE) != 0) 
				{
					f.writeInt(l + 2);
					f.IOPrintf("+ ");
				} 
				else if ((p[0] == '-' || p[0] == '+') && p[1] == ' ') 
				{
					f.writeInt(l + 2);
					f.IOPrintf("- ");
				} 
				else 
					f.writeInt(l);
				f.IOPrintf(p);
				
			}
			f.writeInt(0);
		}
Пример #4
0
        public static int RsyncModule(ClientInfo cInfo, int moduleNumber)
        {
            string   path    = Daemon.config.GetModule(moduleNumber).Path;
            string   name    = Daemon.config.GetModuleName(moduleNumber);
            IOStream f       = cInfo.IoStream;
            Options  options = cInfo.Options;

            string[] args = new string[Options.MAX_ARGS];
            int      argc = 0, maxargs = Options.MAX_ARGS;
            string   line = "";

            if (path[0] == '/')
            {
                path = path.Remove(0, 1);
            }
            path = path.Replace("\n", "");

            Access ac = new Access();

            if (!ac.AllowAccess(options.remoteAddr, options.remoteHost, Daemon.config.GetHostsAllow(moduleNumber), Daemon.config.GetHostsDeny(moduleNumber)))
            {
                Log.Write("rsync denied on module " + name + " from " + options.remoteHost + " (" + options.remoteAddr + ")");
                f.IOPrintf("@ERROR: access denied to " + name + " from " + options.remoteHost + " (" + options.remoteAddr + ")\n");
                return(-1);
            }

            if (!Authentication.AuthServer(cInfo, moduleNumber, options.remoteAddr, "@RSYNCD: AUTHREQD "))
            {
                Log.Write("auth failed on module " + name + " from " + options.remoteHost + " (" + options.remoteAddr + ")\n");
                f.IOPrintf("@ERROR: auth failed on module " + name + "\n");
                return(-1);
            }
// TODO: path length
            if (FileSystem.Directory.Exists(path))
            {
                f.IOPrintf("@RSYNCD: OK\n");
            }
            else
            {
                try
                {
                    // TODO: path length
                    FileSystem.Directory.CreateDirectory(path);
                    f.IOPrintf("@RSYNCD: OK\n");
                }
                catch (Exception) {
                    f.IOPrintf("@ERROR: Path not found\n");
                    MainClass.Exit("@ERROR: Path not found: " + path, cInfo);
                }
            }
            options.amServer = true;                    //to fix error in SetupProtocol
            options.dir      = path;

            while (true)
            {
                line = f.ReadLine();
                line = line.Substring(0, line.Length - 1);
                if (line.CompareTo("") == 0)
                {
                    break;
                }
                if (argc == maxargs)
                {
                    maxargs += Options.MAX_ARGS;
                    MapFile.ReallocArrayString(ref args, maxargs);
                }
                args[argc++] = line;
            }
            args[argc++] = path;

            options.verbose = 0;
            int argsNotUsed = CommandLineParser.ParseArguments(args, options);

            if (argsNotUsed == -1)
            {
                MainClass.Exit("Error parsing options", cInfo);
            }
            string[] args2 = new string[argsNotUsed];
            for (int i = 0; i < argsNotUsed; i++)
            {
                args2[i] = args[args.Length - argsNotUsed + i];
            }


            MainClass.SetupProtocol(cInfo);
            f.IOStartMultiplexOut();
            Daemon.StartServer(cInfo, args2);

            return(-1);
        }
Пример #5
0
        public static int StartInbandExchange(string user, string path, ClientInfo cInfo, int argc)
        {
            Options  options = cInfo.Options;
            IOStream f       = cInfo.IoStream;

            string[] sargs = new string[Options.MAX_ARGS];
            int      sargc = options.ServerOptions(sargs);

            sargs[sargc++] = ".";
            //if(path != null && path.Length>0)
            //sargs[sargc++] = path;

            if (argc == 0 && !options.amSender)
            {
                options.listOnly = true;
            }
            if (path[0] == '/')
            {
                Log.WriteLine("ERROR: The remote path must start with a module name");
                return(-1);
            }
            f.IOPrintf("@RSYNCD: " + options.protocolVersion + "\n");
            string line = f.ReadLine();

            try
            {
                options.remoteProtocol = Int32.Parse(line.Substring(9, 2));
            }
            catch
            {
                options.remoteProtocol = 0;
            }
            bool isValidstring = line.StartsWith("@RSYNCD: ") && line.EndsWith("\n") && options.remoteProtocol > 0;

            if (!isValidstring)
            {
                f.IOPrintf("@ERROR: protocol startup error\n");
                return(-1);
            }
            if (options.protocolVersion > options.remoteProtocol)
            {
                options.protocolVersion = options.remoteProtocol;
            }
            f.IOPrintf(path + "\n");
            while (true)
            {
                line = f.ReadLine();
                if (line.CompareTo("@RSYNCD: OK\n") == 0)
                {
                    break;
                }
                if (line.Length > 18 && line.Substring(0, 18).CompareTo("@RSYNCD: AUTHREQD ") == 0)
                {
                    string pass = String.Empty;
                    if (user.IndexOf(':') != -1)
                    {
                        pass = user.Substring(user.IndexOf(':') + 1);
                        user = user.Substring(0, user.IndexOf(':'));
                    }
                    f.IOPrintf(user + " " + Authentication.AuthorizeClient(user, pass, line.Substring(18).Replace("\n", String.Empty), options) + "\n");
                    continue;
                }

                if (line.CompareTo("@RSYNCD: EXIT\n") == 0)
                {
                    MainClass.Exit("@RSYNCD: EXIT", null);
                }

                if (line.StartsWith("@ERROR: "))
                {
                    MainClass.Exit("Server: " + line.Replace("\n", String.Empty), null);
                }
            }

            for (int i = 0; i < sargc; i++)
            {
                f.IOPrintf(sargs[i] + "\n");
            }
            f.IOPrintf("\n");
            return(0);
        }
Пример #6
0
        public static bool AuthServer(ClientInfo cInfo, int moduleNumber, string addr, string leader)
        {
            string   users = Daemon.config.GetAuthUsers(moduleNumber).Trim();
            string   challenge;
            string   b64_challenge;
            IOStream f = cInfo.IoStream;
            string   line;

            string user   = "";
            string secret = "";
            string pass   = "";
            string pass2  = "";

            string[] listUsers;
            string   tok = "";


            /* if no auth list then allow anyone in! */
            if (users == null || users.CompareTo("") == 0)
            {
                return(true);
            }

            challenge = gen_challenge(addr, cInfo.Options);

            b64_challenge = base64_encode(challenge);

            f.IOPrintf(leader + b64_challenge + "\n");

            line = f.ReadLine();

            if (line.IndexOf(' ') > 0)
            {
                user = line.Substring(0, line.IndexOf(' '));
                pass = line.Substring(line.IndexOf(' ')).Trim('\n').Trim();
            }
            else
            {
                return(false);
            }
            listUsers = users.Split(',');

            for (int i = 0; i < listUsers.Length; i++)
            {
                tok = listUsers[i];
                if (user.CompareTo(tok) == 0)
                {
                    break;
                }
                tok = null;
            }

            if (tok == null || tok.CompareTo("") == 0)
            {
                return(false);
            }

            if ((secret = GetSecret(moduleNumber, user)) == null)
            {
                return(false);
            }

            pass2 = generate_hash(secret, b64_challenge, cInfo.Options);

            if (pass.CompareTo(pass2) == 0)
            {
                return(true);
            }
            return(false);
        }
Пример #7
0
        /// <summary>
        /// Server-side authorization check
        /// </summary>
        /// <param name="clientInfo"></param>
        /// <param name="moduleNumber"></param>
        /// <param name="addr"></param>
        /// <param name="leader"></param>
        /// <returns></returns>
        public static bool AuthorizeServer(ClientInfo clientInfo, int moduleNumber, string addr, string leader)
        {
            string users = Daemon.config.GetAuthUsers(moduleNumber).Trim();
            //string challenge;
            string   b64Challenge;
            IOStream ioStream = clientInfo.IoStream;
            string   line;

            string user   = String.Empty;
            string secret = String.Empty;
            string pass   = String.Empty;
            string pass2  = String.Empty;

            string[] listUsers;
            string   token = String.Empty;

            /* if no auth list then allow anyone in! */
            if (string.IsNullOrEmpty(users))
            {
                return(true);
            }

            b64Challenge = Base64Encode(GenerateChallenge(addr, clientInfo.Options));
            ioStream.IOPrintf(leader + b64Challenge + "\n");

            line = ioStream.ReadLine();

            if (line.IndexOf(' ') > 0)
            {
                user = line.Substring(0, line.IndexOf(' '));
                pass = line.Substring(line.IndexOf(' ')).Trim('\n').Trim();
            }
            else
            {
                return(false);
            }
            listUsers = users.Split(',');

            for (int i = 0; i < listUsers.Length; i++)
            {
                token = listUsers[i];
                if (user.Equals(token))
                {
                    break;
                }
                token = null;
            }

            if (string.IsNullOrEmpty(token))
            {
                return(false);
            }

            if ((secret = GetSecret(moduleNumber, user)) == null)
            {
                return(false);
            }

            pass2 = GenerateHash(secret, b64Challenge, clientInfo.Options);

            if (pass.Equals(pass2))
            {
                return(true);
            }
            return(false);
        }