Esempio n. 1
0
        private void AddBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            var str = request.Form["data"].Value;

            if (string.IsNullOrWhiteSpace(str))
            {
                ReportError(response, bw, "Missing backup object");
                return;
            }

            AddOrUpdateBackupData data = null;
            try
            {
                data = Serializer.Deserialize<AddOrUpdateBackupData>(new StringReader(str));
                if (data.Backup == null)
                {
                    ReportError(response, bw, "Data object had no backup entry");
                    return;
                }

                data.Backup.ID = null;

                if (Duplicati.Library.Utility.Utility.ParseBool(request.Form["temporary"].Value, false))
                {
                    Program.DataConnection.RegisterTemporaryBackup(data.Backup);

                    bw.OutputOK(new { status = "OK", ID = data.Backup.ID });
                }
                else
                {
                    if (Library.Utility.Utility.ParseBool(request.Form["existing_db"].Value, false))
                    {
                        data.Backup.DBPath = Library.Main.DatabaseLocator.GetDatabasePath(data.Backup.TargetURL, null, false, false);
                        if (string.IsNullOrWhiteSpace(data.Backup.DBPath))
                            throw new Exception("Unable to find remote db path?");
                    }

                    lock(Program.DataConnection.m_lock)
                    {
                        if (Program.DataConnection.Backups.Where(x => x.Name.Equals(data.Backup.Name, StringComparison.InvariantCultureIgnoreCase)).Any())
                        {
                            ReportError(response, bw, "There already exists a backup with the name: " + data.Backup.Name);
                            return;
                        }

                        Program.DataConnection.AddOrUpdateBackupAndSchedule(data.Backup, data.Schedule);
                    }

                    bw.OutputOK(new { status = "OK", ID = data.Backup.ID });
                }
            }
            catch (Exception ex)
            {
                if (data == null)
                    ReportError(response, bw, string.Format("Unable to parse backup or schedule object: {0}", ex.Message));
                else
                    ReportError(response, bw, string.Format("Unable to save schedule or backup object: {0}", ex.Message));
            }
        }
Esempio n. 2
0
        private void ReadLogData(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var backupid = input["id"].Value;

            if (string.IsNullOrWhiteSpace(backupid))
            {
                List <Dictionary <string, object> > res = null;
                Program.DataConnection.ExecuteWithCommand(x =>
                {
                    res = DumpTable(x, "ErrorLog", "Timestamp", input["offset"].Value, input["pagesize"].Value);
                });

                bw.OutputOK(res);
            }
            else
            {
                var backup = Program.DataConnection.GetBackup(backupid);
                if (backup == null)
                {
                    ReportError(response, bw, "Invalid or missing backup id");
                    return;
                }

                using (var con = (System.Data.IDbConnection)Activator.CreateInstance(Duplicati.Library.SQLiteHelper.SQLiteLoader.SQLiteConnectionType))
                {
                    con.ConnectionString = "Data Source=" + backup.DBPath;
                    con.Open();

                    using (var cmd = con.CreateCommand())
                    {
                        if (Duplicati.Library.Utility.Utility.ParseBool(input["remotelog"].Value, false))
                        {
                            var dt = DumpTable(cmd, "RemoteOperation", "ID", input["offset"].Value, input["pagesize"].Value);

                            // Unwrap raw data to a string
                            foreach (var n in dt)
                            {
                                try { n["Data"] = System.Text.Encoding.UTF8.GetString((byte[])n["Data"]); }
                                catch { }
                            }

                            bw.OutputOK(dt);
                        }
                        else
                        {
                            var dt = DumpTable(cmd, "LogData", "ID", input["offset"].Value, input["pagesize"].Value);
                            bw.OutputOK(dt);
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        private void ReadLogData(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var backupid = input["id"].Value;

            if (string.IsNullOrWhiteSpace(backupid))
            {
                List<Dictionary<string, object>> res = null;
                Program.DataConnection.ExecuteWithCommand(x =>
                {
                    res = DumpTable(x, "ErrorLog", "Timestamp", input["offset"].Value, input["pagesize"].Value);
                });

                bw.OutputOK(res);
            }
            else
            {
                var backup = Program.DataConnection.GetBackup(backupid);
                if (backup == null)
                {
                    ReportError(response, bw, "Invalid or missing backup id");
                    return;
                }

                using(var con = (System.Data.IDbConnection)Activator.CreateInstance(Duplicati.Library.SQLiteHelper.SQLiteLoader.SQLiteConnectionType))
                {
                    con.ConnectionString = "Data Source=" + backup.DBPath;
                    con.Open();

                    using(var cmd = con.CreateCommand())
                    {
                        if (Duplicati.Library.Utility.Utility.ParseBool(input["remotelog"].Value, false))
                        {
                            var dt = DumpTable(cmd, "RemoteOperation", "ID", input["offset"].Value, input["pagesize"].Value);

                            // Unwrap raw data to a string
                            foreach(var n in dt)
                                try { n["Data"] = System.Text.Encoding.UTF8.GetString((byte[])n["Data"]); }
                            catch { }

                            bw.OutputOK(dt);
                        }
                        else
                        {
                            var dt = DumpTable(cmd, "LogData", "ID", input["offset"].Value, input["pagesize"].Value);
                            bw.OutputOK(dt);
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        private void GetBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var bk = Program.DataConnection.GetBackup(input["id"].Value);

            if (bk == null)
            {
                ReportError(response, bw, "Invalid or missing backup id");
            }
            else
            {
                var scheduleId  = Program.DataConnection.GetScheduleIDsFromTags(new string[] { "ID=" + bk.ID });
                var schedule    = scheduleId.Any() ? Program.DataConnection.GetSchedule(scheduleId.First()) : null;
                var sourcenames = SpecialFolders.GetSourceNames(bk);

                //TODO: Filter out the password in both settings and the target url

                bw.OutputOK(new
                {
                    success = true,
                    data    = new {
                        Schedule     = schedule,
                        Backup       = bk,
                        DisplayNames = sourcenames
                    }
                });
            }
        }
Esempio n. 5
0
        private void GetBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var bk = Program.DataConnection.GetBackup(input["id"].Value);
            if (bk == null)
                ReportError(response, bw, "Invalid or missing backup id");
            else
            {
                var scheduleId = Program.DataConnection.GetScheduleIDsFromTags(new string[] { "ID=" + bk.ID });
                var schedule = scheduleId.Any() ? Program.DataConnection.GetSchedule(scheduleId.First()) : null;
                var sourcenames = GetSourceNames(bk);

                //TODO: Filter out the password in both settings and the target url

                bw.OutputOK(new
                {
                    success = true,
                    data = new {
                        Schedule = schedule,
                        Backup = bk,
                        DisplayNames = sourcenames
                    }
                });
            }
        }
Esempio n. 6
0
        private void SearchBackupFiles(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;

            var filter     = (input["filter"].Value ?? "").Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries);
            var timestring = input["time"].Value;
            var allversion = Duplicati.Library.Utility.Utility.ParseBool(input["all-versions"].Value, false);

            if (string.IsNullOrWhiteSpace(timestring) && !allversion)
            {
                ReportError(response, bw, "Invalid or missing time");
                return;
            }
            var bk = Program.DataConnection.GetBackup(input["id"].Value);

            if (bk == null)
            {
                ReportError(response, bw, "Invalid or missing backup id");
                return;
            }

            var prefixonly     = Duplicati.Library.Utility.Utility.ParseBool(input["prefix-only"].Value, false);
            var foldercontents = Duplicati.Library.Utility.Utility.ParseBool(input["folder-contents"].Value, false);
            var time           = new DateTime();

            if (!allversion)
            {
                time = Duplicati.Library.Utility.Timeparser.ParseTimeInterval(timestring, DateTime.Now);
            }

            var r = Runner.Run(Runner.CreateListTask(bk, filter, prefixonly, allversion, foldercontents, time), false) as Duplicati.Library.Interface.IListResults;

            var result = new Dictionary <string, object>();

            foreach (HttpServer.HttpInputItem n in input)
            {
                result[n.Name] = n.Value;
            }

            result["Filesets"] = r.Filesets;
            result["Files"]    = r.Files;

            bw.OutputOK(result);
        }
Esempio n. 7
0
        private void SearchBackupFiles(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;

            var filter = (input["filter"].Value ?? "").Split(new string[] { System.IO.Path.PathSeparator.ToString() }, StringSplitOptions.RemoveEmptyEntries);
            var timestring = input["time"].Value;
            var allversion = Duplicati.Library.Utility.Utility.ParseBool(input["all-versions"].Value, false);

            if (string.IsNullOrWhiteSpace(timestring) && !allversion)
            {
                ReportError(response, bw, "Invalid or missing time");
                return;
            }
            var bk = Program.DataConnection.GetBackup(input["id"].Value);
            if (bk == null)
            {
                ReportError(response, bw, "Invalid or missing backup id");
                return;
            }

            var prefixonly = Duplicati.Library.Utility.Utility.ParseBool(input["prefix-only"].Value, false);
            var foldercontents = Duplicati.Library.Utility.Utility.ParseBool(input["folder-contents"].Value, false);
            var time = new DateTime();
            if (!allversion)
                time = Duplicati.Library.Utility.Timeparser.ParseTimeInterval(timestring, DateTime.Now);

            var r = Runner.Run(Runner.CreateListTask(bk, filter, prefixonly, allversion, foldercontents, time), false) as Duplicati.Library.Interface.IListResults;

            var result = new Dictionary<string, object>();

            foreach(HttpServer.HttpInputItem n in input)
                result[n.Name] = n.Value;

            result["Filesets"] = r.Filesets;
            result["Files"] = r.Files;

            bw.OutputOK(result);
        }
Esempio n. 8
0
 private void GetLicenseData(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
 {
     bw.OutputOK(Duplicati.License.LicenseReader.ReadLicenses(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Duplicati.Library.Utility.Utility.getEntryAssembly().Location), "licenses")));
 }
Esempio n. 9
0
 private void ListSupportedActions(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
 {
     bw.OutputOK(new { Version = 1, Methods = SUPPORTED_METHODS.Keys });
 }
Esempio n. 10
0
        private void UpdateBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            string str = request.Form["data"].Value;
            if (string.IsNullOrWhiteSpace(str))
            {
                ReportError(response, bw, "Missing backup object");
                return;
            }

            AddOrUpdateBackupData data = null;
            try
            {
                data = Serializer.Deserialize<AddOrUpdateBackupData>(new StringReader(str));
                if (data.Backup == null)
                {
                    ReportError(response, bw, "Data object had no backup entry");
                    return;
                }

                if (data.Backup.ID == null)
                {
                    ReportError(response, bw, "Invalid or missing backup id");
                    return;
                }

                if (data.Backup.IsTemporary)
                {
                    var backup = Program.DataConnection.GetBackup(data.Backup.ID);
                    if (backup.IsTemporary)
                        throw new InvalidDataException("External is temporary but internal is not?");

                    Program.DataConnection.UpdateTemporaryBackup(backup);
                    bw.OutputOK();
                }
                else
                {
                    lock(Program.DataConnection.m_lock)
                    {
                        var backup = Program.DataConnection.GetBackup(data.Backup.ID);
                        if (backup == null)
                        {
                            ReportError(response, bw, "Invalid or missing backup id");
                            return;
                        }

                        if (Program.DataConnection.Backups.Where(x => x.Name.Equals(data.Backup.Name, StringComparison.InvariantCultureIgnoreCase) && x.ID != data.Backup.ID).Any())
                        {
                            ReportError(response, bw, "There already exists a backup with the name: " + data.Backup.Name);
                            return;
                        }

                        //TODO: Merge in real passwords where the placeholder is found
                        Program.DataConnection.AddOrUpdateBackupAndSchedule(data.Backup, data.Schedule);

                    }

                    bw.OutputOK();
                }
            }
            catch (Exception ex)
            {
                if (data == null)
                    ReportError(response, bw, string.Format("Unable to parse backup or schedule object: {0}", ex.Message));
                else
                    ReportError(response, bw, string.Format("Unable to save backup or schedule: {0}", ex.Message));

            }
        }
Esempio n. 11
0
        private void UpdateBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            string str = request.Form["data"].Value;

            if (string.IsNullOrWhiteSpace(str))
            {
                ReportError(response, bw, "Missing backup object");
                return;
            }

            AddOrUpdateBackupData data = null;

            try
            {
                data = Serializer.Deserialize <AddOrUpdateBackupData>(new StringReader(str));
                if (data.Backup == null)
                {
                    ReportError(response, bw, "Data object had no backup entry");
                    return;
                }

                if (data.Backup.ID == null)
                {
                    ReportError(response, bw, "Invalid or missing backup id");
                    return;
                }

                if (data.Backup.IsTemporary)
                {
                    var backup = Program.DataConnection.GetBackup(data.Backup.ID);
                    if (backup.IsTemporary)
                    {
                        throw new InvalidDataException("External is temporary but internal is not?");
                    }

                    Program.DataConnection.UpdateTemporaryBackup(backup);
                    bw.OutputOK();
                }
                else
                {
                    lock (Program.DataConnection.m_lock)
                    {
                        var backup = Program.DataConnection.GetBackup(data.Backup.ID);
                        if (backup == null)
                        {
                            ReportError(response, bw, "Invalid or missing backup id");
                            return;
                        }

                        if (Program.DataConnection.Backups.Where(x => x.Name.Equals(data.Backup.Name, StringComparison.InvariantCultureIgnoreCase) && x.ID != data.Backup.ID).Any())
                        {
                            ReportError(response, bw, "There already exists a backup with the name: " + data.Backup.Name);
                            return;
                        }

                        //TODO: Merge in real passwords where the placeholder is found
                        Program.DataConnection.AddOrUpdateBackupAndSchedule(data.Backup, data.Schedule);
                    }

                    bw.OutputOK();
                }
            }
            catch (Exception ex)
            {
                if (data == null)
                {
                    ReportError(response, bw, string.Format("Unable to parse backup or schedule object: {0}", ex.Message));
                }
                else
                {
                    ReportError(response, bw, string.Format("Unable to save backup or schedule: {0}", ex.Message));
                }
            }
        }
Esempio n. 12
0
        private void DeleteBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var backup = Program.DataConnection.GetBackup(input["id"].Value);

            if (backup == null)
            {
                ReportError(response, bw, "Invalid or missing backup id");
                return;
            }

            if (Program.WorkThread.Active)
            {
                try
                {
                    //TODO: It's not safe to access the values like this,
                    //because the runner thread might interfere
                    var nt = Program.WorkThread.CurrentTask;
                    if (backup.Equals(nt == null ? null : nt.Backup))
                    {
                        bool force;
                        if (!bool.TryParse(input["force"].Value, out force))
                        {
                            force = false;
                        }

                        if (!force)
                        {
                            bw.WriteJsonObject(new { status = "failed", reason = "backup-in-progress" });
                            return;
                        }

                        bool hasPaused = Program.LiveControl.State == LiveControls.LiveControlState.Paused;
                        Program.LiveControl.Pause();

                        try
                        {
                            for (int i = 0; i < 10; i++)
                            {
                                if (Program.WorkThread.Active)
                                {
                                    var t = Program.WorkThread.CurrentTask;
                                    if (backup.Equals(t == null ? null : t.Backup))
                                    {
                                        System.Threading.Thread.Sleep(1000);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                        finally
                        {
                        }

                        if (Program.WorkThread.Active)
                        {
                            var t = Program.WorkThread.CurrentTask;
                            if (backup.Equals(t == null ? null : t.Backup))
                            {
                                if (hasPaused)
                                {
                                    Program.LiveControl.Resume();
                                }
                                bw.WriteJsonObject(new { status = "failed", reason = "backup-unstoppable" });
                                return;
                            }
                        }

                        if (hasPaused)
                        {
                            Program.LiveControl.Resume();
                        }
                    }
                }
                catch (Exception ex)
                {
                    bw.WriteJsonObject(new { status = "error", message = ex.Message });
                    return;
                }
            }


            //var dbpath = backup.DBPath;
            Program.DataConnection.DeleteBackup(backup);

            // TODO: Before we activate this,
            // we need some strategy to figure out
            // if the db is shared with something else
            // like the commandline or another backup

            /*try
             * {
             *  if (System.IO.File.Exists(dbpath))
             *      System.IO.File.Delete(dbpath);
             * }
             * catch (Exception ex)
             * {
             *  Program.DataConnection.LogError(null, string.Format("Failed to delete database: {0}", dbpath), ex);
             * }*/

            //We have fiddled with the schedules
            Program.Scheduler.Reschedule();

            bw.OutputOK();
        }
Esempio n. 13
0
        public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;

            var authcookie = request.Cookies[AUTH_COOKIE_NAME] ?? request.Cookies[Library.Utility.Uri.UrlEncode(AUTH_COOKIE_NAME)];
            var authinput  = input["auth-token"] ?? input[Library.Utility.Uri.UrlEncode("auth-token")];

            var auth_token = authcookie == null || string.IsNullOrWhiteSpace(authcookie.Value) ? null : authcookie.Value;

            if (authinput != null && !string.IsNullOrWhiteSpace(authinput.Value))
            {
                auth_token = input["auth-token"].Value;
            }

            if (request.Uri.AbsolutePath == "/logout.cgi")
            {
                if (!string.IsNullOrWhiteSpace(auth_token))
                {
                    if (m_activeTokens.ContainsKey(auth_token))
                    {
                        m_activeTokens.Remove(auth_token);
                    }
                }

                response.Status = System.Net.HttpStatusCode.NoContent;
                response.Reason = "OK";

                return(true);
            }
            else if (request.Uri.AbsolutePath == "/login.cgi")
            {
                foreach (var k in (from n in m_activeNonces where DateTime.UtcNow > n.Value.Item1 select n.Key).ToList())
                {
                    m_activeNonces.Remove(k);
                }

                if (input["get-nonce"] != null && !string.IsNullOrWhiteSpace(input["get-nonce"].Value))
                {
                    if (m_activeNonces.Count > 50)
                    {
                        response.Status = System.Net.HttpStatusCode.ServiceUnavailable;
                        response.Reason = "Too many active login attempts";
                        return(true);
                    }

                    var buf     = new byte[32];
                    var expires = DateTime.UtcNow.AddMinutes(10);
                    m_prng.GetBytes(buf);
                    var nonce = Convert.ToBase64String(buf);

                    var sha256 = System.Security.Cryptography.SHA256.Create();
                    sha256.TransformBlock(buf, 0, buf.Length, buf, 0);
                    buf = Convert.FromBase64String(Program.DataConnection.ApplicationSettings.WebserverPassword);
                    sha256.TransformFinalBlock(buf, 0, buf.Length);
                    var pwd = Convert.ToBase64String(sha256.Hash);

                    m_activeNonces.Add(nonce, new Tuple <DateTime, string>(expires, pwd));

                    response.Cookies.Add(new HttpServer.ResponseCookie(NONCE_COOKIE_NAME, nonce, expires));
                    using (var bw = new BodyWriter(response))
                    {
                        bw.OutputOK(new {
                            Status = "OK",
                            Nonce  = nonce,
                            Salt   = Program.DataConnection.ApplicationSettings.WebserverPasswordSalt
                        });
                    }
                    return(true);
                }
                else
                {
                    if (input["password"] != null && !string.IsNullOrWhiteSpace(input["password"].Value))
                    {
                        var nonce_el   = request.Cookies[NONCE_COOKIE_NAME] ?? request.Cookies[Library.Utility.Uri.UrlEncode(NONCE_COOKIE_NAME)];
                        var nonce      = nonce_el == null || string.IsNullOrWhiteSpace(nonce_el.Value) ? "" : nonce_el.Value;
                        var urldecoded = nonce == null ? "" : Duplicati.Library.Utility.Uri.UrlDecode(nonce);
                        if (m_activeNonces.ContainsKey(urldecoded))
                        {
                            nonce = urldecoded;
                        }

                        if (!m_activeNonces.ContainsKey(nonce))
                        {
                            response.Status      = System.Net.HttpStatusCode.Unauthorized;
                            response.Reason      = "Unauthorized";
                            response.ContentType = "application/json";
                            return(true);
                        }

                        var pwd = m_activeNonces[nonce].Item2;
                        m_activeNonces.Remove(nonce);

                        if (pwd != input["password"].Value)
                        {
                            response.Status      = System.Net.HttpStatusCode.Unauthorized;
                            response.Reason      = "Unauthorized";
                            response.ContentType = "application/json";
                            return(true);
                        }

                        var buf     = new byte[32];
                        var expires = DateTime.UtcNow.AddHours(1);
                        m_prng.GetBytes(buf);
                        var token = Duplicati.Library.Utility.Utility.Base64UrlEncode(buf);
                        while (token.Length > 0 && token.EndsWith("="))
                        {
                            token = token.Substring(0, token.Length - 1);
                        }

                        m_activeTokens.Add(token, expires);
                        response.Cookies.Add(new  HttpServer.ResponseCookie(AUTH_COOKIE_NAME, token, expires));

                        using (var bw = new BodyWriter(response))
                            bw.OutputOK();

                        return(true);
                    }
                }
            }

            if (string.IsNullOrWhiteSpace(Program.DataConnection.ApplicationSettings.WebserverPassword))
            {
                return(false);
            }

            foreach (var k in (from n in m_activeTokens where DateTime.UtcNow > n.Value select n.Key).ToList())
            {
                m_activeTokens.Remove(k);
            }


            // If we have a valid token, proceeed
            if (!string.IsNullOrWhiteSpace(auth_token))
            {
                DateTime expires;
                var      found = m_activeTokens.TryGetValue(auth_token, out expires);
                if (!found)
                {
                    auth_token = Duplicati.Library.Utility.Uri.UrlDecode(auth_token);
                    found      = m_activeTokens.TryGetValue(auth_token, out expires);
                }

                if (found && DateTime.UtcNow < expires)
                {
                    expires = DateTime.UtcNow.AddHours(1);
                    m_activeTokens[auth_token] = expires;
                    response.Cookies.Add(new ResponseCookie(AUTH_COOKIE_NAME, auth_token, expires));
                    return(false);
                }
            }

            if (request.Uri.AbsolutePath == "/" || request.Uri.AbsolutePath == "/index.html")
            {
                response.Redirect("/login.html");
                return(true);
            }

            if (request.Uri.AbsolutePath == "/control.cgi")
            {
                response.Status = System.Net.HttpStatusCode.Unauthorized;
                response.Reason = "Not logged in";
                response.AddHeader("Location", "login.html");

                return(true);
            }

            return(false);
        }
Esempio n. 14
0
 private void GetNotifications(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
 {
     bw.OutputOK(Program.DataConnection.GetNotifications());
 }
Esempio n. 15
0
        public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;

            var auth_token = FindAuthCookie(request);
            var xsrf_token = FindXSRFToken(request);

            if (!HasXSRFCookie(request))
            {
                var cookieAdded = AddXSRFTokenToRespone(response);

                if (!cookieAdded)
                {
                    response.Status = System.Net.HttpStatusCode.ServiceUnavailable;
                    response.Reason = "Too Many Concurrent Request, try again later";
                    return(true);
                }
            }

            if (LOGOUT_SCRIPT_URI.Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
            {
                if (!string.IsNullOrWhiteSpace(auth_token))
                {
                    if (m_activeTokens.ContainsKey(auth_token))
                    {
                        m_activeTokens.Remove(auth_token);
                    }
                }

                response.Status = System.Net.HttpStatusCode.NoContent;
                response.Reason = "OK";

                return(true);
            }
            else if (LOGIN_SCRIPT_URI.Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
            {
                foreach (var k in (from n in m_activeNonces where DateTime.UtcNow > n.Value.Item1 select n.Key).ToList())
                {
                    m_activeNonces.Remove(k);
                }

                if (input["get-nonce"] != null && !string.IsNullOrWhiteSpace(input["get-nonce"].Value))
                {
                    if (m_activeNonces.Count > 50)
                    {
                        response.Status = System.Net.HttpStatusCode.ServiceUnavailable;
                        response.Reason = "Too many active login attempts";
                        return(true);
                    }

                    var buf     = new byte[32];
                    var expires = DateTime.UtcNow.AddMinutes(AUTH_TIMEOUT_MINUTES);
                    m_prng.GetBytes(buf);
                    var nonce = Convert.ToBase64String(buf);

                    var sha256 = System.Security.Cryptography.SHA256.Create();
                    sha256.TransformBlock(buf, 0, buf.Length, buf, 0);
                    buf = Convert.FromBase64String(Program.DataConnection.ApplicationSettings.WebserverPassword);
                    sha256.TransformFinalBlock(buf, 0, buf.Length);
                    var pwd = Convert.ToBase64String(sha256.Hash);

                    m_activeNonces.Add(nonce, new Tuple <DateTime, string>(expires, pwd));

                    response.Cookies.Add(new HttpServer.ResponseCookie(NONCE_COOKIE_NAME, nonce, expires));
                    using (var bw = new BodyWriter(response, request))
                    {
                        bw.OutputOK(new {
                            Status = "OK",
                            Nonce  = nonce,
                            Salt   = Program.DataConnection.ApplicationSettings.WebserverPasswordSalt
                        });
                    }
                    return(true);
                }
                else
                {
                    if (input["password"] != null && !string.IsNullOrWhiteSpace(input["password"].Value))
                    {
                        var nonce_el   = request.Cookies[NONCE_COOKIE_NAME] ?? request.Cookies[Library.Utility.Uri.UrlEncode(NONCE_COOKIE_NAME)];
                        var nonce      = nonce_el == null || string.IsNullOrWhiteSpace(nonce_el.Value) ? "" : nonce_el.Value;
                        var urldecoded = nonce == null ? "" : Duplicati.Library.Utility.Uri.UrlDecode(nonce);
                        if (m_activeNonces.ContainsKey(urldecoded))
                        {
                            nonce = urldecoded;
                        }

                        if (!m_activeNonces.ContainsKey(nonce))
                        {
                            response.Status      = System.Net.HttpStatusCode.Unauthorized;
                            response.Reason      = "Unauthorized";
                            response.ContentType = "application/json";
                            return(true);
                        }

                        var pwd = m_activeNonces[nonce].Item2;
                        m_activeNonces.Remove(nonce);

                        if (pwd != input["password"].Value)
                        {
                            response.Status      = System.Net.HttpStatusCode.Unauthorized;
                            response.Reason      = "Unauthorized";
                            response.ContentType = "application/json";
                            return(true);
                        }

                        var buf     = new byte[32];
                        var expires = DateTime.UtcNow.AddHours(1);
                        m_prng.GetBytes(buf);
                        var token = Duplicati.Library.Utility.Utility.Base64UrlEncode(buf);
                        while (token.Length > 0 && token.EndsWith("="))
                        {
                            token = token.Substring(0, token.Length - 1);
                        }

                        m_activeTokens.Add(token, expires);
                        response.Cookies.Add(new  HttpServer.ResponseCookie(AUTH_COOKIE_NAME, token, expires));

                        using (var bw = new BodyWriter(response, request))
                            bw.OutputOK();

                        return(true);
                    }
                }
            }

            var limitedAccess =
                ControlHandler.CONTROL_HANDLER_URI.Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase)
                ||
                request.Uri.AbsolutePath.StartsWith(RESTHandler.API_URI_PATH, StringComparison.InvariantCultureIgnoreCase)
            ;

            if (limitedAccess)
            {
                if (xsrf_token != null && m_activexsrf.ContainsKey(xsrf_token))
                {
                    var expires = DateTime.UtcNow.AddMinutes(XSRF_TIMEOUT_MINUTES);
                    m_activexsrf[xsrf_token] = expires;
                    response.Cookies.Add(new ResponseCookie(XSRF_COOKIE_NAME, xsrf_token, expires));
                }
                else
                {
                    response.Status = System.Net.HttpStatusCode.BadRequest;
                    response.Reason = "Missing XSRF Token";

                    return(true);
                }
            }

            if (string.IsNullOrWhiteSpace(Program.DataConnection.ApplicationSettings.WebserverPassword))
            {
                return(false);
            }

            foreach (var k in (from n in m_activeTokens where DateTime.UtcNow > n.Value select n.Key).ToList())
            {
                m_activeTokens.Remove(k);
            }


            // If we have a valid token, proceeed
            if (!string.IsNullOrWhiteSpace(auth_token))
            {
                DateTime expires;
                var      found = m_activeTokens.TryGetValue(auth_token, out expires);
                if (!found)
                {
                    auth_token = Duplicati.Library.Utility.Uri.UrlDecode(auth_token);
                    found      = m_activeTokens.TryGetValue(auth_token, out expires);
                }

                if (found && DateTime.UtcNow < expires)
                {
                    expires = DateTime.UtcNow.AddHours(1);
                    m_activeTokens[auth_token] = expires;
                    response.Cookies.Add(new ResponseCookie(AUTH_COOKIE_NAME, auth_token, expires));
                    return(false);
                }
            }

            if ("/".Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase) || "/index.html".Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
            {
                response.Redirect("/login.html");
                return(true);
            }

            if (ControlHandler.CONTROL_HANDLER_URI.Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
            {
                response.Status = System.Net.HttpStatusCode.Unauthorized;
                response.Reason = "Not logged in";
                response.AddHeader("Location", "login.html");

                return(true);
            }

            return(false);
        }
Esempio n. 16
0
        private void SetServerOptions(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            string str = request.Form["data"].Value;
            if (string.IsNullOrWhiteSpace(str))
            {
                ReportError(response, bw, "Missing data object");
                return;
            }

            Dictionary<string, string> data = null;
            try
            {
                data = Serializer.Deserialize<Dictionary<string, string>>(new StringReader(str));
                if (data == null)
                {
                    ReportError(response, bw, "Data object had no backup entry");
                    return;
                }

                Program.DataConnection.ApplicationSettings.UpdateSettings(data);

                bw.OutputOK();
            }
            catch (Exception ex)
            {
                if (data == null)
                    ReportError(response, bw, string.Format("Unable to parse data object: {0}", ex.Message));
                else
                    ReportError(response, bw, string.Format("Unable to save settings: {0}", ex.Message));
            }

        }
Esempio n. 17
0
        private void ExportBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var bk = Program.DataConnection.GetBackup(input["id"].Value);
            if (bk == null)
            {
                ReportError(response, bw, "Invalid or missing backup id");
                return;
            }

            var cmdline = Library.Utility.Utility.ParseBool(input["cmdline"].Value, false);
            if (cmdline)
            {
                bw.OutputOK(new { Command = Runner.GetCommandLine(Runner.CreateTask(DuplicatiOperation.Backup, bk)) });
            }
            else
            {
                var passphrase = input["passphrase"].Value;
                var scheduleId = Program.DataConnection.GetScheduleIDsFromTags(new string[] { "ID=" + bk.ID });

                var ipx = new ImportExportStructure() {
                    CreatedByVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(),
                    Backup = (Database.Backup)bk,
                    Schedule = (Database.Schedule)(scheduleId.Any() ? Program.DataConnection.GetSchedule(scheduleId.First()) : null),
                    DisplayNames = GetSourceNames(bk)
                };

                byte[] data;
                using(var ms = new System.IO.MemoryStream())
                using(var sw = new System.IO.StreamWriter(ms))
                {
                    Serializer.SerializeJson(sw, ipx, true);

                    if (!string.IsNullOrWhiteSpace(passphrase))
                    {
                        ms.Position = 0;
                        using(var ms2 = new System.IO.MemoryStream())
                        using(var m = new Duplicati.Library.Encryption.AESEncryption(passphrase, new Dictionary<string, string>()))
                        {
                            m.Encrypt(ms, ms2);
                            data = ms2.ToArray();
                        }
                    }
                    else
                        data = ms.ToArray();
                }

                var filename = Library.Utility.Uri.UrlEncode(bk.Name) + "-duplicati-config.json";
                if (!string.IsNullOrWhiteSpace(passphrase))
                    filename += ".aes";

                response.ContentLength = data.Length;
                response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", filename));
                response.ContentType = "application/octet-stream";

                bw.SetOK();
                response.SendHeaders();
                response.SendBody(data);
            }
        }
Esempio n. 18
0
        private void GetServerOptions(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            var adv_props = from n in Program.DataConnection.GetSettings(Database.Connection.APP_SETTINGS_ID)
                            select new KeyValuePair<string, string>(n.Name, n.Value);

            bw.OutputOK(adv_props.ToDictionary(x => x.Key, x => x.Value));
        }
Esempio n. 19
0
        private void DeleteLocalData(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var bk = Program.DataConnection.GetBackup(input["id"].Value);
            if (bk == null)
            {
                ReportError(response, bw, "Invalid or missing backup id");
                return;
            }

            System.IO.File.Delete(bk.DBPath);
            bw.OutputOK();
        }
Esempio n. 20
0
 private void ListApplicationSettings(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
 {
     bw.OutputOK(Program.DataConnection.ApplicationSettings);
 }
Esempio n. 21
0
 private void ListCoreOptions(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
 {
     bw.OutputOK(new Duplicati.Library.Main.Options(new Dictionary<string, string>()).SupportedCommands);
 }
Esempio n. 22
0
        private void DismissNotification(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var str = input["id"].Value;
            long id;
            long.TryParse(str, out id);

            if (Program.DataConnection.DismissNotification(id))
                bw.OutputOK();
            else
                ReportError(response, bw, "No such notification");

        }
Esempio n. 23
0
 private void GetProgressState(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
 {
     if (Program.GenerateProgressState == null)
     {
         ReportError(response, bw, "No active backup");
     }
     else
     {
         var ev = Program.GenerateProgressState();
         bw.OutputOK(ev);
     }
 }
Esempio n. 24
0
        private void GetUISettings(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var scheme = input["scheme"].Value;
            if (string.IsNullOrWhiteSpace(scheme))
            {
                ReportError(response, bw, "No scheme supplied");
                return;
            }

            bw.OutputOK(Program.DataConnection.GetUISettings(scheme));
        }
Esempio n. 25
0
 private void ListSupportedActions(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
 {
     bw.OutputOK(new { Version = 1, Methods = SUPPORTED_METHODS.Keys });
 }
Esempio n. 26
0
        private void SetUISettings(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var scheme = input["scheme"].Value;
            var str = input["data"].Value;
            if (string.IsNullOrWhiteSpace(scheme))
            {
                ReportError(response, bw, "No scheme supplied");
                return;
            }

            if (string.IsNullOrWhiteSpace(str))
            {
                ReportError(response, bw, "No data supplied");
                return;
            }

            IDictionary<string, string> data;
            try
            {
                data = Serializer.Deserialize<Dictionary<string, string>>(new StringReader(str));
            }
            catch (Exception ex)
            {
                ReportError(response, bw, string.Format("Unable to parse settings object: {0}", ex.Message));
                return;
            }

            if (data == null)
            {
                ReportError(response, bw, string.Format("Unable to parse settings object"));
                return;
            }

            Program.DataConnection.SetUISettings(scheme, data);
            bw.OutputOK();
        }
Esempio n. 27
0
        private void ValidatePath(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            if (input["path"] == null || input["path"].Value == null)
            {
                ReportError(response, bw, "The path parameter was not set");
                return;
            }

            try
            {
                string path = SpecialFolders.ExpandEnvironmentVariables(input["path"].Value);                
                if (System.IO.Path.IsPathRooted(path) && System.IO.Directory.Exists(path))
                {
                    bw.OutputOK();
                    return;
                }
            }
            catch
            {
            }

            ReportError(response, bw, "File or folder not found");
            return;
        }
Esempio n. 28
0
 private void GetUISettingSchemes(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
 {
     bw.OutputOK(Program.DataConnection.GetUISettingsSchemes());
 }
Esempio n. 29
0
        private void ListTags(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            var r = 
                from n in 
                Serializable.ServerSettings.CompressionModules
                    .Union(Serializable.ServerSettings.EncryptionModules)
                    .Union(Serializable.ServerSettings.BackendModules)
                    .Union(Serializable.ServerSettings.GenericModules)
                    select n.Key.ToLower();

            // Append all known tags
            r = r.Union(from n in Program.DataConnection.Backups select n.Tags into p from x in p select x.ToLower());
            bw.OutputOK(r);
        }
Esempio n. 30
0
        private void GetFolderContents(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            if (input["path"] == null || input["path"].Value == null)
            {
                ReportError(response, bw, "The path parameter was not set");
                return;
            }

            bool skipFiles = Library.Utility.Utility.ParseBool(input["onlyfolders"].Value, false);

            var path = input["path"].Value;
            string specialpath = null;
            string specialtoken = null;

            if (path.StartsWith("%"))
            {
                var ix = path.IndexOf("%", 1);
                if (ix > 0)
                {
                    var tk = path.Substring(0, ix + 1);
                    var node = SpecialFolders.Nodes.Where(x => x.id.Equals(tk, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                    if (node != null)
                    {
                        specialpath = node.resolvedpath;
                        specialtoken = node.id;
                    }
                }
            }

            path = SpecialFolders.ExpandEnvironmentVariables(path);

            if (Duplicati.Library.Utility.Utility.IsClientLinux && !path.StartsWith("/"))
            {
                ReportError(response, bw, "The path parameter must start with a forward-slash");
                return;
            }

            try
            {
                if (path != "" && path != "/")
                    path = Duplicati.Library.Utility.Utility.AppendDirSeparator(path);

                IEnumerable<Serializable.TreeNode> res;

                if (!Library.Utility.Utility.IsClientLinux && (path.Equals("/") || path.Equals("")))
                {
                    res =
                        from di in System.IO.DriveInfo.GetDrives()
                            where di.DriveType == DriveType.Fixed || di.DriveType == DriveType.Network || di.DriveType == DriveType.Removable
                        select new Serializable.TreeNode()
                    {
                        id = di.RootDirectory.FullName,
                        text = di.RootDirectory.FullName.Replace('\\', ' ') + "(" + di.DriveType + ")",
                        iconCls = "x-tree-icon-drive"
                    };
                }
                else
                {
                    res = ListFolderAsNodes(path, skipFiles);
                }

                if ((path.Equals("/") || path.Equals("")) && specialtoken == null)
                {
                    // Prepend special folders
                    res = SpecialFolders.Nodes.Union(res);
                }

                if (specialtoken != null)
                {
                    res = from n in res
                        select new Serializable.TreeNode() {
                        id = specialtoken + n.id.Substring(specialpath.Length),
                        text = n.text,
                        iconCls = n.iconCls,
                        leaf = n.leaf,
                        resolvedpath = n.id
                    };
                }

                bw.OutputOK(res);
            }
            catch (Exception ex)
            {
                ReportError(response, bw, "Failed to process the path: " + ex.Message);
            }
        }
Esempio n. 31
0
        private void AddBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            var str = request.Form["data"].Value;

            if (string.IsNullOrWhiteSpace(str))
            {
                ReportError(response, bw, "Missing backup object");
                return;
            }

            AddOrUpdateBackupData data = null;

            try
            {
                data = Serializer.Deserialize <AddOrUpdateBackupData>(new StringReader(str));
                if (data.Backup == null)
                {
                    ReportError(response, bw, "Data object had no backup entry");
                    return;
                }

                data.Backup.ID = null;

                if (Duplicati.Library.Utility.Utility.ParseBool(request.Form["temporary"].Value, false))
                {
                    Program.DataConnection.RegisterTemporaryBackup(data.Backup);

                    bw.OutputOK(new { status = "OK", ID = data.Backup.ID });
                }
                else
                {
                    if (Library.Utility.Utility.ParseBool(request.Form["existing_db"].Value, false))
                    {
                        data.Backup.DBPath = Library.Main.DatabaseLocator.GetDatabasePath(data.Backup.TargetURL, null, false, false);
                        if (string.IsNullOrWhiteSpace(data.Backup.DBPath))
                        {
                            throw new Exception("Unable to find remote db path?");
                        }
                    }


                    lock (Program.DataConnection.m_lock)
                    {
                        if (Program.DataConnection.Backups.Where(x => x.Name.Equals(data.Backup.Name, StringComparison.InvariantCultureIgnoreCase)).Any())
                        {
                            ReportError(response, bw, "There already exists a backup with the name: " + data.Backup.Name);
                            return;
                        }

                        Program.DataConnection.AddOrUpdateBackupAndSchedule(data.Backup, data.Schedule);
                    }

                    bw.OutputOK(new { status = "OK", ID = data.Backup.ID });
                }
            }
            catch (Exception ex)
            {
                if (data == null)
                {
                    ReportError(response, bw, string.Format("Unable to parse backup or schedule object: {0}", ex.Message));
                }
                else
                {
                    ReportError(response, bw, string.Format("Unable to save schedule or backup object: {0}", ex.Message));
                }
            }
        }
Esempio n. 32
0
        public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;

            var auth_token = FindAuthCookie(request);
            var xsrf_token = FindXSRFToken(request);

            if (!HasXSRFCookie(request))
            {
                var cookieAdded = AddXSRFTokenToRespone(response);

                if (!cookieAdded)
                {
                    response.Status = System.Net.HttpStatusCode.ServiceUnavailable;
                    response.Reason = "Too Many Concurrent Request, try again later";
                    return(true);
                }
            }
            Tuple <DateTime, string> tmpTuple;
            DateTime tmpDateTime;

            if (LOGOUT_SCRIPT_URI.Equals(request.Uri.AbsolutePath, StringComparison.OrdinalIgnoreCase))
            {
                if (!string.IsNullOrWhiteSpace(auth_token))
                {
                    // Remove the active auth token
                    m_activeTokens.TryRemove(auth_token, out tmpDateTime);
                }

                response.Status = System.Net.HttpStatusCode.NoContent;
                response.Reason = "OK";

                return(true);
            }
            else if (LOGIN_SCRIPT_URI.Equals(request.Uri.AbsolutePath, StringComparison.OrdinalIgnoreCase))
            {
                // Remove expired nonces
                foreach (var k in (from n in m_activeNonces where DateTime.UtcNow > n.Value.Item1 select n.Key))
                {
                    m_activeNonces.TryRemove(k, out tmpTuple);
                }

                if (input["get-nonce"] != null && !string.IsNullOrWhiteSpace(input["get-nonce"].Value))
                {
                    if (m_activeNonces.Count > 50)
                    {
                        response.Status = System.Net.HttpStatusCode.ServiceUnavailable;
                        response.Reason = "Too many active login attempts";
                        return(true);
                    }

                    var password = Program.DataConnection.ApplicationSettings.WebserverPassword;

                    if (request.Headers[TRAYICONPASSWORDSOURCE_HEADER] == "database")
                    {
                        password = Program.DataConnection.ApplicationSettings.WebserverPasswordTrayIconHash;
                    }

                    var buf     = new byte[32];
                    var expires = DateTime.UtcNow.AddMinutes(AUTH_TIMEOUT_MINUTES);
                    m_prng.GetBytes(buf);
                    var nonce = Convert.ToBase64String(buf);

                    var sha256 = System.Security.Cryptography.SHA256.Create();
                    sha256.TransformBlock(buf, 0, buf.Length, buf, 0);
                    buf = Convert.FromBase64String(password);
                    sha256.TransformFinalBlock(buf, 0, buf.Length);
                    var pwd = Convert.ToBase64String(sha256.Hash);

                    m_activeNonces.AddOrUpdate(nonce, key => new Tuple <DateTime, string>(expires, pwd), (key, existingValue) =>
                    {
                        // Simulate the original behavior => if the nonce, against all odds, is already used
                        // we throw an ArgumentException
                        throw new ArgumentException("An element with the same key already exists in the dictionary.");
                    });

                    response.Cookies.Add(new HttpServer.ResponseCookie(NONCE_COOKIE_NAME, nonce, expires));
                    using (var bw = new BodyWriter(response, request))
                    {
                        bw.OutputOK(new {
                            Status = "OK",
                            Nonce  = nonce,
                            Salt   = Program.DataConnection.ApplicationSettings.WebserverPasswordSalt
                        });
                    }
                    return(true);
                }
                else
                {
                    if (input["password"] != null && !string.IsNullOrWhiteSpace(input["password"].Value))
                    {
                        var nonce_el   = request.Cookies[NONCE_COOKIE_NAME] ?? request.Cookies[Library.Utility.Uri.UrlEncode(NONCE_COOKIE_NAME)];
                        var nonce      = nonce_el == null || string.IsNullOrWhiteSpace(nonce_el.Value) ? "" : nonce_el.Value;
                        var urldecoded = nonce == null ? "" : Duplicati.Library.Utility.Uri.UrlDecode(nonce);
                        if (m_activeNonces.ContainsKey(urldecoded))
                        {
                            nonce = urldecoded;
                        }

                        if (!m_activeNonces.ContainsKey(nonce))
                        {
                            response.Status      = System.Net.HttpStatusCode.Unauthorized;
                            response.Reason      = "Unauthorized";
                            response.ContentType = "application/json";
                            return(true);
                        }

                        var pwd = m_activeNonces[nonce].Item2;

                        // Remove the nonce
                        m_activeNonces.TryRemove(nonce, out tmpTuple);

                        if (pwd != input["password"].Value)
                        {
                            response.Status      = System.Net.HttpStatusCode.Unauthorized;
                            response.Reason      = "Unauthorized";
                            response.ContentType = "application/json";
                            return(true);
                        }

                        var buf     = new byte[32];
                        var expires = DateTime.UtcNow.AddHours(1);
                        m_prng.GetBytes(buf);
                        var token = Duplicati.Library.Utility.Utility.Base64UrlEncode(buf);
                        while (token.Length > 0 && token.EndsWith("=", StringComparison.Ordinal))
                        {
                            token = token.Substring(0, token.Length - 1);
                        }

                        m_activeTokens.AddOrUpdate(token, key => expires, (key, existingValue) =>
                        {
                            // Simulate the original behavior => if the token, against all odds, is already used
                            // we throw an ArgumentException
                            throw new ArgumentException("An element with the same key already exists in the dictionary.");
                        });

                        response.Cookies.Add(new  HttpServer.ResponseCookie(AUTH_COOKIE_NAME, token, expires));

                        using (var bw = new BodyWriter(response, request))
                            bw.OutputOK();

                        return(true);
                    }
                }
            }

            var limitedAccess =
                request.Uri.AbsolutePath.StartsWith(RESTHandler.API_URI_PATH, StringComparison.OrdinalIgnoreCase)
            ;

            // Override to allow the CAPTCHA call to go through
            if (request.Uri.AbsolutePath.StartsWith(CAPTCHA_IMAGE_URI, StringComparison.OrdinalIgnoreCase) && request.Method == "GET")
            {
                limitedAccess = false;
            }

            if (limitedAccess)
            {
                if (xsrf_token != null && m_activexsrf.ContainsKey(xsrf_token))
                {
                    var expires = DateTime.UtcNow.AddMinutes(XSRF_TIMEOUT_MINUTES);
                    m_activexsrf[xsrf_token] = expires;
                    response.Cookies.Add(new ResponseCookie(XSRF_COOKIE_NAME, xsrf_token, expires));
                }
                else
                {
                    response.Status = System.Net.HttpStatusCode.BadRequest;
                    response.Reason = "Missing XSRF Token. Please reload the page";

                    return(true);
                }
            }

            if (string.IsNullOrWhiteSpace(Program.DataConnection.ApplicationSettings.WebserverPassword))
            {
                return(false);
            }

            foreach (var k in (from n in m_activeTokens where DateTime.UtcNow > n.Value select n.Key))
            {
                m_activeTokens.TryRemove(k, out tmpDateTime);
            }


            // If we have a valid token, proceed
            if (!string.IsNullOrWhiteSpace(auth_token))
            {
                DateTime expires;
                var      found = m_activeTokens.TryGetValue(auth_token, out expires);
                if (!found)
                {
                    auth_token = Duplicati.Library.Utility.Uri.UrlDecode(auth_token);
                    found      = m_activeTokens.TryGetValue(auth_token, out expires);
                }

                if (found && DateTime.UtcNow < expires)
                {
                    expires = DateTime.UtcNow.AddHours(1);

                    m_activeTokens[auth_token] = expires;
                    response.Cookies.Add(new ResponseCookie(AUTH_COOKIE_NAME, auth_token, expires));
                    return(false);
                }
            }

            if ("/".Equals(request.Uri.AbsolutePath, StringComparison.OrdinalIgnoreCase) || "/index.html".Equals(request.Uri.AbsolutePath, StringComparison.OrdinalIgnoreCase))
            {
                response.Redirect("/login.html");
                return(true);
            }

            if (limitedAccess)
            {
                response.Status = System.Net.HttpStatusCode.Unauthorized;
                response.Reason = "Not logged in";
                response.AddHeader("Location", "login.html");

                return(true);
            }

            return(false);
        }
Esempio n. 33
0
        private void ListBackups (HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            var schedules = Program.DataConnection.Schedules;
            var backups = Program.DataConnection.Backups;

            var all = from n in backups
                select new AddOrUpdateBackupData() {
                Backup = (Database.Backup)n,
                Schedule = 
                    (from x in schedules
                        where x.Tags != null && x.Tags.Contains("ID=" + n.ID)
                        select (Database.Schedule)x).FirstOrDefault()
                };

            bw.OutputOK(all.ToArray());
        }
Esempio n. 34
0
        private void TestBackend(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            if (input["url"] == null || input["url"].Value == null)
            {
                ReportError(response, bw, "The url parameter was not set");
                return;
            }

            var modules = (from n in Library.DynamicLoader.GenericLoader.Modules
                                    where n is Library.Interface.IConnectionModule
                                    select n).ToArray();

            try
            {
                var url = input["url"].Value;
                var uri = new Library.Utility.Uri(url);
                var qp = uri.QueryParameters;

                var opts = new Dictionary<string, string>();
                foreach(var k in qp.Keys.Cast<string>())
                    opts[k] = qp[k];

                foreach(var n in modules)
                    n.Configure(opts);

                using(var b = Duplicati.Library.DynamicLoader.BackendLoader.GetBackend(url, new Dictionary<string, string>()))
                    b.Test();

                bw.OutputOK();
            }
            catch (Duplicati.Library.Interface.FolderMissingException)
            {
                ReportError(response, bw, "missing-folder");
            }
            catch (Duplicati.Library.Utility.SslCertificateValidator.InvalidCertificateException icex)
            {
                if (string.IsNullOrWhiteSpace(icex.Certificate))
                    ReportError(response, bw, icex.Message);
                else
                    ReportError(response, bw, "incorrect-cert:" + icex.Certificate);
            }
            catch (Exception ex)
            {
                ReportError(response, bw, ex.Message);
            }
            finally
            {
                foreach(var n in modules)
                    if (n is IDisposable)
                        ((IDisposable)n).Dispose();
            }
        }
Esempio n. 35
0
 private void ListSystemInfo(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
 {
     bw.OutputOK(new
     {
         APIVersion = 1,
         PasswordPlaceholder = Duplicati.Server.WebServer.Server.PASSWORD_PLACEHOLDER,
         ServerVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(),
         ServerVersionName = Duplicati.License.VersionNumbers.Version,
         ServerTime = DateTime.Now,
         OSType = Library.Utility.Utility.IsClientLinux ? (Library.Utility.Utility.IsClientOSX ? "OSX" : "Linux") : "Windows",
         DirectorySeparator = System.IO.Path.DirectorySeparatorChar,
         PathSeparator = System.IO.Path.PathSeparator,
         CaseSensitiveFilesystem = Duplicati.Library.Utility.Utility.IsFSCaseSensitive,
         MonoVersion = Duplicati.Library.Utility.Utility.IsMono ? Duplicati.Library.Utility.Utility.MonoVersion.ToString() : null,
         MachineName = System.Environment.MachineName,
         NewLine = System.Environment.NewLine,
         CLRVersion = System.Environment.Version.ToString(),
         CLROSInfo = new
         {
             Platform = System.Environment.OSVersion.Platform.ToString(),
             ServicePack = System.Environment.OSVersion.ServicePack,
             Version = System.Environment.OSVersion.Version.ToString(),
             VersionString = System.Environment.OSVersion.VersionString
         },
         Options = Serializable.ServerSettings.Options,
         CompressionModules =  Serializable.ServerSettings.CompressionModules,
         EncryptionModules = Serializable.ServerSettings.EncryptionModules,
         BackendModules = Serializable.ServerSettings.BackendModules,
         GenericModules = Serializable.ServerSettings.GenericModules,
         WebModules = Serializable.ServerSettings.WebModules,
         ConnectionModules = Serializable.ServerSettings.ConnectionModules,
         UsingAlternateUpdateURLs = Duplicati.Library.AutoUpdater.AutoUpdateSettings.UsesAlternateURLs,
         LogLevels = Enum.GetNames(typeof(Duplicati.Library.Logging.LogMessageType))
     });
 }
Esempio n. 36
0
        private void DeleteBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var backup = Program.DataConnection.GetBackup(input["id"].Value);

            if (backup == null)
            {
                ReportError(response, bw, "Invalid or missing backup id");
                return;
            }

            if (Program.WorkThread.Active)
            {
                try
                {
                    //TODO: It's not safe to access the values like this,
                    //because the runner thread might interfere
                    var nt = Program.WorkThread.CurrentTask;
                    if (backup.Equals(nt == null ? null : nt.Backup))
                    {
                        bool force;
                        if (!bool.TryParse(input["force"].Value, out force))
                        {
                            force = false;
                        }

                        if (!force)
                        {
                            bw.WriteJsonObject(new { status = "failed", reason = "backup-in-progress" });
                            return;
                        }

                        bool hasPaused = Program.LiveControl.State == LiveControls.LiveControlState.Paused;
                        Program.LiveControl.Pause();

                        try
                        {
                            for (int i = 0; i < 10; i++)
                            {
                                if (Program.WorkThread.Active)
                                {
                                    var t = Program.WorkThread.CurrentTask;
                                    if (backup.Equals(t == null ? null : t.Backup))
                                    {
                                        System.Threading.Thread.Sleep(1000);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                        finally
                        {
                        }

                        if (Program.WorkThread.Active)
                        {
                            var t = Program.WorkThread.CurrentTask;
                            if (backup.Equals(t == null ? null : t.Backup))
                            {
                                if (hasPaused)
                                {
                                    Program.LiveControl.Resume();
                                }
                                bw.WriteJsonObject(new { status = "failed", reason = "backup-unstoppable" });
                                return;
                            }
                        }

                        if (hasPaused)
                        {
                            Program.LiveControl.Resume();
                        }
                    }
                }
                catch (Exception ex)
                {
                    bw.WriteJsonObject(new { status = "error", message = ex.Message });
                    return;
                }
            }

            Program.DataConnection.DeleteBackup(backup);

            //We have fiddled with the schedules
            Program.Scheduler.Reschedule();

            bw.OutputOK();
        }
Esempio n. 37
0
        private void GetBackupDefaults(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {   
            // Start with a scratch object
            var o = new Newtonsoft.Json.Linq.JObject();

            // Add application wide settings
            o.Add("ApplicationOptions", new Newtonsoft.Json.Linq.JArray(Program.DataConnection.Settings));

            try
            {
                // Add built-in defaults
                Newtonsoft.Json.Linq.JObject n;
                using(var s = new System.IO.StreamReader(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".newbackup.json")))
                    n = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(s.ReadToEnd());

                MergeJsonObjects(o, n);
            }
            catch
            {
            }

            try
            {
                // Add install defaults/overrides, if present
                var path = System.IO.Path.Combine(Duplicati.Library.AutoUpdater.UpdaterManager.InstalledBaseDir, "newbackup.json");
                if (System.IO.File.Exists(path))
                {
                    Newtonsoft.Json.Linq.JObject n;
                    n = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(System.IO.File.ReadAllText(path));

                    MergeJsonObjects(o, n);
                }
            }
            catch
            {
            }

            bw.OutputOK(new
            {
                success = true,
                data = o
            });
        }
Esempio n. 38
0
 private void GetCurrentState (HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
 {
     bool isError;
     long id = 0;
     if (LongPollCheck(request, response, bw, Program.StatusEventNotifyer, ref id, out isError))
     {
         //Make sure we do not report a higher number than the eventnotifyer says
         var st = new Serializable.ServerStatus();
         st.LastEventID = id;
         bw.OutputOK(st);
     }
     else if (!isError)
     {
         bw.OutputOK(new Serializable.ServerStatus());
     }
 }
Esempio n. 39
0
        private void DeleteBackup(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var backup = Program.DataConnection.GetBackup(input["id"].Value);
            if (backup == null)
            {
                ReportError(response, bw, "Invalid or missing backup id");
                return;
            }

            if (Program.WorkThread.Active)
            {
                try
                {
                    //TODO: It's not safe to access the values like this,
                    //because the runner thread might interfere
                    var nt = Program.WorkThread.CurrentTask;
                    if (backup.Equals(nt == null ? null : nt.Backup))
                    {
                        bool force;
                        if (!bool.TryParse(input["force"].Value, out force))
                            force = false;

                        if (!force)
                        {
                            bw.WriteJsonObject(new { status = "failed", reason = "backup-in-progress" });
                            return;
                        }

                        bool hasPaused = Program.LiveControl.State == LiveControls.LiveControlState.Paused;
                        Program.LiveControl.Pause();

                        try
                        {
                            for (int i = 0; i < 10; i++)
                                if (Program.WorkThread.Active)
                                {
                                    var t = Program.WorkThread.CurrentTask;
                                    if (backup.Equals(t == null ? null : t.Backup))
                                        System.Threading.Thread.Sleep(1000);
                                    else
                                        break;
                                }
                                else
                                    break;
                        }
                        finally
                        {
                        }

                        if (Program.WorkThread.Active)
                        {
                            var t = Program.WorkThread.CurrentTask;
                            if (backup.Equals(t == null ? null : t.Backup))
                            {
                                if (hasPaused)
                                    Program.LiveControl.Resume();
                                bw.WriteJsonObject(new { status = "failed", reason = "backup-unstoppable" });
                                return;
                            }
                        }

                        if (hasPaused)
                            Program.LiveControl.Resume();
                    }
                }
                catch (Exception ex)
                {
                    bw.WriteJsonObject(new { status = "error", message = ex.Message });
                    return;
                }
            }

            Program.DataConnection.DeleteBackup(backup);

            //We have fiddled with the schedules
            Program.Scheduler.Reschedule();

            bw.OutputOK();
        }
Esempio n. 40
0
        private void PollLogMessages(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            var level_str = input["level"].Value ?? "";
            var id_str = input["id"].Value ?? "";

            Library.Logging.LogMessageType level;
            long id;

            long.TryParse(id_str, out id);
            Enum.TryParse(level_str, true, out level);

            bw.OutputOK(Program.LogHandler.AfterID(id, level));
        }
Esempio n. 41
0
        public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;

            var auth_token = FindAuthCookie(request);
            var xsrf_token = FindXSRFToken(request);

            if (!HasXSRFCookie(request))
            {
                var cookieAdded = AddXSRFTokenToRespone(response);

                if (!cookieAdded)
                {
                    response.Status = System.Net.HttpStatusCode.ServiceUnavailable;
                    response.Reason = "Too Many Concurrent Request, try again later";
                    return true;
                }
			}
			Tuple<DateTime, string> tmpTuple;
			DateTime tmpDateTime;

			if (LOGOUT_SCRIPT_URI.Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
            {
                if (!string.IsNullOrWhiteSpace(auth_token))
                {
					// Remove the active auth token
	                m_activeTokens.TryRemove(auth_token, out tmpDateTime);
                }

                response.Status = System.Net.HttpStatusCode.NoContent;
                response.Reason = "OK";

                return true;
            }
            else if (LOGIN_SCRIPT_URI.Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
            {
				// Remove expired nonces
                foreach(var k in (from n in m_activeNonces where DateTime.UtcNow > n.Value.Item1 select n.Key))
                    m_activeNonces.TryRemove(k, out tmpTuple);

                if (input["get-nonce"] != null && !string.IsNullOrWhiteSpace(input["get-nonce"].Value))
                {
                    if (m_activeNonces.Count > 50)
                    {
                        response.Status = System.Net.HttpStatusCode.ServiceUnavailable;
                        response.Reason = "Too many active login attempts";
                        return true;
                    }

                    var buf = new byte[32];
                    var expires = DateTime.UtcNow.AddMinutes(AUTH_TIMEOUT_MINUTES);
                    m_prng.GetBytes(buf);
                    var nonce = Convert.ToBase64String(buf);

                    var sha256 = System.Security.Cryptography.SHA256.Create();
                    sha256.TransformBlock(buf, 0, buf.Length, buf, 0);
                    buf = Convert.FromBase64String(Program.DataConnection.ApplicationSettings.WebserverPassword);
                    sha256.TransformFinalBlock(buf, 0, buf.Length);
                    var pwd = Convert.ToBase64String(sha256.Hash);

					m_activeNonces.AddOrUpdate(nonce, key => new Tuple<DateTime, string>(expires, pwd), (key, existingValue) =>
					{
						// Simulate the original behavior => if the nonce, against all odds, is already used
						// we throw an ArgumentException
						throw new ArgumentException("An element with the same key already exists in the dictionary.");
					});

                    response.Cookies.Add(new HttpServer.ResponseCookie(NONCE_COOKIE_NAME, nonce, expires));
                    using(var bw = new BodyWriter(response, request))
                    {
                        bw.OutputOK(new {
                            Status = "OK",
                            Nonce = nonce,
                            Salt = Program.DataConnection.ApplicationSettings.WebserverPasswordSalt
                        });
                    }
                    return true;
                }
                else
                {
                    if (input["password"] != null && !string.IsNullOrWhiteSpace(input["password"].Value))
                    {
                        var nonce_el = request.Cookies[NONCE_COOKIE_NAME] ?? request.Cookies[Library.Utility.Uri.UrlEncode(NONCE_COOKIE_NAME)];
                        var nonce = nonce_el == null || string.IsNullOrWhiteSpace(nonce_el.Value) ? "" : nonce_el.Value;
                        var urldecoded = nonce == null ? "" : Duplicati.Library.Utility.Uri.UrlDecode(nonce);
                        if (m_activeNonces.ContainsKey(urldecoded))
                            nonce = urldecoded;

                        if (!m_activeNonces.ContainsKey(nonce))
                        {
                            response.Status = System.Net.HttpStatusCode.Unauthorized;
                            response.Reason = "Unauthorized";
                            response.ContentType = "application/json";
                            return true;
                        }

						var pwd = m_activeNonces[nonce].Item2;

						// Remove the nonce
                        m_activeNonces.TryRemove(nonce, out tmpTuple);

                        if (pwd != input["password"].Value)
                        {
                            response.Status = System.Net.HttpStatusCode.Unauthorized;
                            response.Reason = "Unauthorized";
                            response.ContentType = "application/json";
                            return true;
                        }

                        var buf = new byte[32];
                        var expires = DateTime.UtcNow.AddHours(1);
                        m_prng.GetBytes(buf);
                        var token = Duplicati.Library.Utility.Utility.Base64UrlEncode(buf);
                        while (token.Length > 0 && token.EndsWith("="))
                            token = token.Substring(0, token.Length - 1);

						m_activeTokens.AddOrUpdate(token, key => expires, (key, existingValue) =>
						{
							// Simulate the original behavior => if the token, against all odds, is already used
							// we throw an ArgumentException
							throw new ArgumentException("An element with the same key already exists in the dictionary.");
						});

						response.Cookies.Add(new  HttpServer.ResponseCookie(AUTH_COOKIE_NAME, token, expires));

                        using(var bw = new BodyWriter(response, request))
                            bw.OutputOK();

                        return true;
                    }
                }
            }

            var limitedAccess =
                ControlHandler.CONTROL_HANDLER_URI.Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase)
                ||
                request.Uri.AbsolutePath.StartsWith(RESTHandler.API_URI_PATH, StringComparison.InvariantCultureIgnoreCase)
            ;

            if (limitedAccess)
            {
                if (xsrf_token != null && m_activexsrf.ContainsKey(xsrf_token))
                {
                    var expires = DateTime.UtcNow.AddMinutes(XSRF_TIMEOUT_MINUTES);
                    m_activexsrf[xsrf_token] = expires;
                    response.Cookies.Add(new ResponseCookie(XSRF_COOKIE_NAME, xsrf_token, expires));
                }
                else
                {
                    response.Status = System.Net.HttpStatusCode.BadRequest;
                    response.Reason = "Missing XSRF Token";

                    return true;
                }
            }

            if (string.IsNullOrWhiteSpace(Program.DataConnection.ApplicationSettings.WebserverPassword))
                return false;

            foreach(var k in (from n in m_activeTokens where DateTime.UtcNow > n.Value select n.Key))
                m_activeTokens.TryRemove(k, out tmpDateTime);


            // If we have a valid token, proceed
            if (!string.IsNullOrWhiteSpace(auth_token))
            {
                DateTime expires;
                var found = m_activeTokens.TryGetValue(auth_token, out expires);
                if (!found)
                {
                    auth_token = Duplicati.Library.Utility.Uri.UrlDecode(auth_token);
                    found = m_activeTokens.TryGetValue(auth_token, out expires);
                }

                if (found && DateTime.UtcNow < expires)
                {
                    expires = DateTime.UtcNow.AddHours(1);

					m_activeTokens[auth_token] = expires;
                    response.Cookies.Add(new ResponseCookie(AUTH_COOKIE_NAME, auth_token, expires));
                    return false;
                }
            }

            if ("/".Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase) || "/index.html".Equals(request.Uri.AbsolutePath, StringComparison.InvariantCultureIgnoreCase))
            {
                response.Redirect("/login.html");
                return true;
            }
                
            if (limitedAccess)
            {
                response.Status = System.Net.HttpStatusCode.Unauthorized;
                response.Reason = "Not logged in";
                response.AddHeader("Location", "login.html");

                return true;
            }

            return false;
        }
Esempio n. 42
0
        private void GetFolderContents(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session, BodyWriter bw)
        {
            HttpServer.HttpInput input = request.Method.ToUpper() == "POST" ? request.Form : request.QueryString;
            if (input["path"] == null || input["path"].Value == null)
            {
                ReportError(response, bw, "The path parameter was not set");
                return;
            }

            bool skipFiles = Library.Utility.Utility.ParseBool(input["onlyfolders"].Value, false);

            var    path         = input["path"].Value;
            string specialpath  = null;
            string specialtoken = null;

            if (path.StartsWith("%"))
            {
                var ix = path.IndexOf("%", 1);
                if (ix > 0)
                {
                    var tk   = path.Substring(0, ix + 1);
                    var node = SpecialFolders.Nodes.Where(x => x.id.Equals(tk, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
                    if (node != null)
                    {
                        specialpath  = node.resolvedpath;
                        specialtoken = node.id;
                    }
                }
            }

            path = SpecialFolders.ExpandEnvironmentVariables(path);

            if (Duplicati.Library.Utility.Utility.IsClientLinux && !path.StartsWith("/"))
            {
                ReportError(response, bw, "The path parameter must start with a forward-slash");
                return;
            }

            try
            {
                if (path != "" && path != "/")
                {
                    path = Duplicati.Library.Utility.Utility.AppendDirSeparator(path);
                }

                IEnumerable <Serializable.TreeNode> res;

                if (!Library.Utility.Utility.IsClientLinux && (path.Equals("/") || path.Equals("")))
                {
                    res =
                        from di in System.IO.DriveInfo.GetDrives()
                        where di.DriveType == DriveType.Fixed || di.DriveType == DriveType.Network || di.DriveType == DriveType.Removable
                        select new Serializable.TreeNode()
                    {
                        id      = di.RootDirectory.FullName,
                        text    = di.RootDirectory.FullName.Replace('\\', ' ') + "(" + di.DriveType + ")",
                        iconCls = "x-tree-icon-drive"
                    };
                }
                else
                {
                    res = ListFolderAsNodes(path, skipFiles);
                }

                if ((path.Equals("/") || path.Equals("")) && specialtoken == null)
                {
                    // Prepend special folders
                    res = SpecialFolders.Nodes.Union(res);
                }

                if (specialtoken != null)
                {
                    res = from n in res
                          select new Serializable.TreeNode()
                    {
                        id           = specialtoken + n.id.Substring(specialpath.Length),
                        text         = n.text,
                        iconCls      = n.iconCls,
                        leaf         = n.leaf,
                        resolvedpath = n.id
                    };
                }

                bw.OutputOK(res);
            }
            catch (Exception ex)
            {
                ReportError(response, bw, "Failed to process the path: " + ex.Message);
            }
        }