diff --git a/router/router_server_files.go b/router/router_server_files.go index eca7390..ecfd116 100644 --- a/router/router_server_files.go +++ b/router/router_server_files.go @@ -441,6 +441,8 @@ type chmodFile struct { Mode string `json:"mode"` } +var errInvalidFileMode = errors.New("invalid file mode") + func postServerChmodFile(c *gin.Context) { s := GetServer(c.Param("server")) @@ -472,7 +474,7 @@ func postServerChmodFile(c *gin.Context) { default: mode, err := strconv.ParseUint(p.Mode, 8, 32) if err != nil { - return err + return errInvalidFileMode } if err := s.Filesystem().Chmod(path.Join(data.Root, p.File), os.FileMode(mode)); err != nil { @@ -491,6 +493,13 @@ func postServerChmodFile(c *gin.Context) { } if err := g.Wait(); err != nil { + if errors.Is(err, errInvalidFileMode) { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ + "error": "Invalid file mode.", + }) + return + } + NewServerError(err, s).AbortFilesystemError(c) return } diff --git a/router/router_transfer.go b/router/router_transfer.go index 16bf1a1..8aa27ed 100644 --- a/router/router_transfer.go +++ b/router/router_transfer.go @@ -326,6 +326,7 @@ func postTransfer(c *gin.Context) { } else { i.Server().SetTransferring(false) i.Server().Events().Publish(server.TransferStatusEvent, "success") + sendTransferLog("Transfer completed.") } }(i.Server()) @@ -449,8 +450,9 @@ func postTransfer(c *gin.Context) { // It may be useful to retry sending the transfer success every so often just in case of a small // hiccup or the fix of whatever error causing the success request to fail. hasError = false - data.log().Info("archive transfered successfully, notifying panel of status") - sendTransferLog("Archive transfered successfully.") + + data.log().Info("archive transferred successfully, notifying panel of status") + sendTransferLog("Archive transferred successfully.") }(&data) c.Status(http.StatusAccepted) diff --git a/server/backup.go b/server/backup.go index 10dbe1e..95d5629 100644 --- a/server/backup.go +++ b/server/backup.go @@ -31,7 +31,10 @@ func (s *Server) notifyPanelOfBackup(uuid string, ad *backup.ArchiveDetails, suc // Get all of the ignored files for a server based on its .pteroignore file in the root. func (s *Server) getServerwideIgnoredFiles() (string, error) { - f, err := os.Open(path.Join(s.Filesystem().Path(), ".pteroignore")) + p := path.Join(s.Filesystem().Path(), ".pteroignore") + + // Stat the file and don't resolve any symlink targets. + stat, err := os.Lstat(p) if err != nil { if !os.IsNotExist(err) { return "", err @@ -40,6 +43,26 @@ func (s *Server) getServerwideIgnoredFiles() (string, error) { return "", nil } + // Do not read directories or symlinks. + if stat.Mode()&os.ModeDir != 0 || stat.Mode()&os.ModeSymlink != 0 { + return "", nil + } + + // If the file is bigger than 32 KiB, don't read it at all. + if stat.Size() > 32*1024 { + return "", nil + } + + f, err := os.Open(p) + if err != nil { + if !os.IsNotExist(err) { + return "", err + } + + return "", nil + } + + // Read the entire file into memory. b, err := ioutil.ReadAll(f) if err != nil { return "", err @@ -75,7 +98,7 @@ func (s *Server) Backup(b backup.BackupInterface) error { }).Info("notified panel of failed backup state") } - s.Events().PublishJson(BackupCompletedEvent+":"+b.Identifier(), map[string]interface{}{ + _ = s.Events().PublishJson(BackupCompletedEvent+":"+b.Identifier(), map[string]interface{}{ "uuid": b.Identifier(), "is_successful": false, "checksum": "",