1""" 2BitBake SFTP Fetch implementation 3 4Class for fetching files via SFTP. It tries to adhere to the (now 5expired) IETF Internet Draft for "Uniform Resource Identifier (URI) 6Scheme for Secure File Transfer Protocol (SFTP) and Secure Shell 7(SSH)" (SECSH URI). 8 9It uses SFTP (as to adhere to the SECSH URI specification). It only 10supports key based authentication, not password. This class, unlike 11the SSH fetcher, does not support fetching a directory tree from the 12remote. 13 14 http://tools.ietf.org/html/draft-ietf-secsh-scp-sftp-ssh-uri-04 15 https://www.iana.org/assignments/uri-schemes/prov/sftp 16 https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13 17 18Please note that '/' is used as host path seperator, and not ":" 19as you may be used to from the scp/sftp commands. You can use a 20~ (tilde) to specify a path relative to your home directory. 21(The /~user/ syntax, for specyfing a path relative to another 22user's home directory is not supported.) Note that the tilde must 23still follow the host path seperator ("/"). See exampels below. 24 25Example SRC_URIs: 26 27SRC_URI = "sftp://host.example.com/dir/path.file.txt" 28 29A path relative to your home directory. 30 31SRC_URI = "sftp://host.example.com/~/dir/path.file.txt" 32 33You can also specify a username (specyfing password in the 34URI is not supported, use SSH keys to authenticate): 35 36SRC_URI = "sftp://user@host.example.com/dir/path.file.txt" 37 38""" 39 40# Copyright (C) 2013, Olof Johansson <olof.johansson@axis.com> 41# 42# Based in part on bb.fetch2.wget: 43# Copyright (C) 2003, 2004 Chris Larson 44# 45# SPDX-License-Identifier: GPL-2.0-only 46# 47# Based on functions from the base bb module, Copyright 2003 Holger Schurig 48 49import os 50import bb 51import urllib.request, urllib.parse, urllib.error 52from bb.fetch2 import URI 53from bb.fetch2 import FetchMethod 54from bb.fetch2 import runfetchcmd 55 56class SFTP(FetchMethod): 57 """Class to fetch urls via 'sftp'""" 58 59 def supports(self, ud, d): 60 """ 61 Check to see if a given url can be fetched with sftp. 62 """ 63 return ud.type in ['sftp'] 64 65 def recommends_checksum(self, urldata): 66 return True 67 68 def urldata_init(self, ud, d): 69 if 'protocol' in ud.parm and ud.parm['protocol'] == 'git': 70 raise bb.fetch2.ParameterError( 71 "Invalid protocol - if you wish to fetch from a " + 72 "git repository using ssh, you need to use the " + 73 "git:// prefix with protocol=ssh", ud.url) 74 75 if 'downloadfilename' in ud.parm: 76 ud.basename = ud.parm['downloadfilename'] 77 else: 78 ud.basename = os.path.basename(ud.path) 79 80 ud.localfile = d.expand(urllib.parse.unquote(ud.basename)) 81 82 def download(self, ud, d): 83 """Fetch urls""" 84 85 urlo = URI(ud.url) 86 basecmd = 'sftp -oBatchMode=yes' 87 port = '' 88 if urlo.port: 89 port = '-P %d' % urlo.port 90 urlo.port = None 91 92 dldir = d.getVar('DL_DIR') 93 lpath = os.path.join(dldir, ud.localfile) 94 95 user = '' 96 if urlo.userinfo: 97 user = urlo.userinfo + '@' 98 99 path = urlo.path 100 101 # Supoprt URIs relative to the user's home directory, with 102 # the tilde syntax. (E.g. <sftp://example.com/~/foo.diff>). 103 if path[:3] == '/~/': 104 path = path[3:] 105 106 remote = '%s%s:%s' % (user, urlo.hostname, path) 107 108 cmd = '%s %s %s %s' % (basecmd, port, remote, lpath) 109 110 bb.fetch2.check_network_access(d, cmd, ud.url) 111 runfetchcmd(cmd, d) 112 return True 113