代码拉取完成,页面将自动刷新
同步操作将从 tupelo-shen/mysnapd 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2017 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package userd
import (
"bytes"
"fmt"
"net/url"
"os"
"os/exec"
"regexp"
"syscall"
"time"
"github.com/godbus/dbus"
"gitee.com/mysnapcore/mysnapd/i18n"
"gitee.com/mysnapcore/mysnapd/logger"
"gitee.com/mysnapcore/mysnapd/osutil"
"gitee.com/mysnapcore/mysnapd/osutil/sys"
"gitee.com/mysnapcore/mysnapd/release"
"gitee.com/mysnapcore/mysnapd/strutil"
"gitee.com/mysnapcore/mysnapd/usersession/userd/ui"
)
const launcherIntrospectionXML = `
<interface name="org.freedesktop.DBus.Peer">
<method name='Ping'>
</method>
<method name='GetMachineId'>
<arg type='s' name='machine_uuid' direction='out'/>
</method>
</interface>
<interface name='io.snapcraft.Launcher'>
<method name='OpenURL'>
<arg type='s' name='url' direction='in'/>
</method>
<method name="OpenFile">
<arg type="s" name="parent_window" direction="in"/>
<arg type="h" name="fd" direction="in"/>
</method>
</interface>`
// allowedURLSchemes are those that can be passed to xdg-open so that it may
// launch the handler for the url scheme on behalf of the snap (and therefore
// outside of the calling snap's confinement). Historically we've been
// conservative about adding url schemes but the thinking was refined in
// https://github.com/snapcore/snapd/pull/7731#pullrequestreview-362900171
//
// The current criteria for adding url schemes is:
// * understanding and documenting the scheme in this file
// * the scheme itself does not cause xdg-open to open files (eg, file:// or
// matching '^[[:alpha:]+\.\-]+:' (from xdg-open source))
// * verifying that the recipient of the url (ie, what xdg-open calls) won't
// process file paths/etc that can be leveraged to break out of the sandbox
// (but understanding how the url can drive the recipient application is
// important)
//
// This code uses golang's net/url.Parse() which will help ensure the url is
// ok before passing to xdg-open. xdg-open itself properly quotes the url so
// shell metacharacters are blocked.
var (
allowedURLSchemes = []string{
// apt: the scheme allows specifying a package for xdg-open to pass to an
// apt-handling application, like gnome-software, apturl, etc which are all
// protected by policykit
// - scheme: apt:<name of package>
// - https://github.com/snapcore/snapd/pull/7731
"apt",
// help: the scheme allows for specifying a help URL. This code ensures that
// the url is parseable
// - scheme: help://topic
// - https://github.com/snapcore/snapd/pull/6493
"help",
// http/https: the scheme allows specifying a web URL. This code ensures that
// the url is parseable
// - scheme: http(s)://example.com
"http",
"https",
// mailto: the scheme allows for specifying an email address
// - scheme: mailto:foo@example.com
"mailto",
// msteams: the scheme is a thin wrapper around https.
// - scheme: msteams:...
// - https://github.com/snapcore/snapd/pull/8761
"msteams",
// TODO: document slack URL scheme.
"slack",
// snap: the scheme allows specifying a package for xdg-open to pass to a
// snap-handling installer application, like snap-store, etc which are
// protected by policykit/snap login
// - https://github.com/snapcore/snapd/pull/5181
"snap",
// zoommtg: the scheme is a modified web url scheme
// - scheme: https://medium.com/zoom-developer-blog/zoom-url-schemes-748b95fd9205
// (eg, zoommtg://zoom.us/...)
// - https://github.com/snapcore/snapd/pull/8304
"zoommtg",
// zoomphonecall: another zoom URL scheme, for dialing phone numbers
// - https://github.com/snapcore/snapd/pull/8910
"zoomphonecall",
// zoomus: alternative name for zoommtg
// - https://github.com/snapcore/snapd/pull/8910
"zoomus",
}
)
// Launcher implements the 'io.snapcraft.Launcher' DBus interface.
type Launcher struct {
conn *dbus.Conn
}
// Interface returns the name of the interface this object implements
func (s *Launcher) Interface() string {
return "io.snapcraft.Launcher"
}
// ObjectPath returns the path that the object is exported as
func (s *Launcher) ObjectPath() dbus.ObjectPath {
return "/io/snapcraft/Launcher"
}
// IntrospectionData gives the XML formatted introspection description
// of the DBus service.
func (s *Launcher) IntrospectionData() string {
return launcherIntrospectionXML
}
func makeAccessDeniedError(err error) *dbus.Error {
return &dbus.Error{
Name: "org.freedesktop.DBus.Error.AccessDenied",
Body: []interface{}{err.Error()},
}
}
func checkOnClassic() *dbus.Error {
if !release.OnClassic {
return makeAccessDeniedError(fmt.Errorf("not supported on Ubuntu Core"))
}
return nil
}
// see https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#file-naming
var validDesktopFileName = regexp.MustCompile(`^[A-Za-z-_][A-Za-z0-9-_]*(\.[A-Za-z-_][A-Za-z0-9-_]*)*\.desktop$`)
func schemeHasHandler(scheme string) (bool, error) {
cmd := exec.Command("xdg-mime", "query", "default", "x-scheme-handler/"+scheme)
// TODO: consider using Output() in case xdg-mime starts logging to
// stderr
out, err := cmd.CombinedOutput()
if err != nil {
return false, osutil.OutputErr(out, err)
}
out = bytes.TrimSpace(out)
// if the output is a valid desktop file we have a handler for the given
// scheme
return validDesktopFileName.Match(out), nil
}
// OpenURL implements the 'OpenURL' method of the 'io.snapcraft.Launcher'
// DBus interface. Before the provided url is passed to xdg-open the scheme is
// validated against a list of allowed schemes. All other schemes are denied.
func (s *Launcher) OpenURL(addr string, sender dbus.Sender) *dbus.Error {
logger.Debugf("open url: %q", addr)
if err := checkOnClassic(); err != nil {
return err
}
u, err := url.Parse(addr)
if err != nil {
return &dbus.ErrMsgInvalidArg
}
if u.Scheme == "" {
return makeAccessDeniedError(fmt.Errorf("cannot open URL without a scheme"))
}
isAllowed := strutil.ListContains(allowedURLSchemes, u.Scheme)
if !isAllowed {
// scheme is not listed in our allowed schemes list, perform
// fallback and check whether the local system has a handler for
// it
isAllowed, err = schemeHasHandler(u.Scheme)
if err != nil {
logger.Noticef("cannot obtain scheme handler for %q: %v", u.Scheme, err)
}
}
if !isAllowed {
return makeAccessDeniedError(fmt.Errorf("Supplied URL scheme %q is not allowed", u.Scheme))
}
if err := exec.Command("xdg-open", addr).Run(); err != nil {
return dbus.MakeFailedError(fmt.Errorf("cannot open supplied URL"))
}
return nil
}
// fdToFilename determines the path associated with an open file descriptor.
//
// The file descriptor cannot be opened using O_PATH and must refer to
// a regular file or to a directory. The symlink at /proc/self/fd/<fd>
// is read to determine the filename. The descriptor is also fstat'ed
// and the resulting device number and inode number are compared to
// stat on the path determined earlier. The numbers must match.
func fdToFilename(fd int) (string, error) {
flags, err := sys.FcntlGetFl(fd)
if err != nil {
return "", err
}
// File descriptors opened with O_PATH do not imply access to
// the file in question.
if flags&sys.O_PATH != 0 {
return "", fmt.Errorf("cannot use file descriptors opened using O_PATH")
}
// Determine the file name associated with the passed file descriptor.
filename, err := os.Readlink(fmt.Sprintf("/proc/self/fd/%d", fd))
if err != nil {
return "", err
}
var fileStat, fdStat syscall.Stat_t
if err := syscall.Stat(filename, &fileStat); err != nil {
return "", err
}
if err := syscall.Fstat(fd, &fdStat); err != nil {
return "", err
}
// check to ensure we've got the right file
if fdStat.Dev != fileStat.Dev || fdStat.Ino != fileStat.Ino {
return "", fmt.Errorf("cannot determine file name")
}
fileType := fileStat.Mode & syscall.S_IFMT
if fileType != syscall.S_IFREG && fileType != syscall.S_IFDIR {
return "", fmt.Errorf("cannot open anything other than regular files or directories")
}
return filename, nil
}
func (s *Launcher) OpenFile(parentWindow string, clientFd dbus.UnixFD, sender dbus.Sender) *dbus.Error {
// godbus transfers ownership of this file descriptor to us
fd := int(clientFd)
defer syscall.Close(fd)
if err := checkOnClassic(); err != nil {
return err
}
filename, err := fdToFilename(fd)
if err != nil {
return dbus.MakeFailedError(err)
}
snap, err := snapFromSender(s.conn, sender)
if err != nil {
return dbus.MakeFailedError(err)
}
dialog, err := ui.New()
if err != nil {
return dbus.MakeFailedError(err)
}
answeredYes := dialog.YesNo(
i18n.G("Allow opening file?"),
fmt.Sprintf(i18n.G("Allow snap %q to open file %q?"), snap, filename),
&ui.DialogOptions{
Timeout: 5 * 60 * time.Second,
Footer: i18n.G("This dialog will close automatically after 5 minutes of inactivity."),
},
)
if !answeredYes {
return dbus.MakeFailedError(fmt.Errorf("permission denied"))
}
if err = exec.Command("xdg-open", filename).Run(); err != nil {
return dbus.MakeFailedError(fmt.Errorf("cannot open supplied URL"))
}
return nil
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。