blob: f87f292e5d80213d379c01269bd01f9e371e8631 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001"""
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#
Brad Bishopc342db32019-05-15 21:57:59 -040045# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -050046#
47# Based on functions from the base bb module, Copyright 2003 Holger Schurig
48
49import os
50import bb
Patrick Williamsc0f7c042017-02-23 20:41:17 -060051import urllib.request, urllib.parse, urllib.error
Patrick Williamsc124f4f2015-09-15 14:41:29 -050052from bb.fetch2 import URI
53from bb.fetch2 import FetchMethod
54from bb.fetch2 import runfetchcmd
55
Patrick Williamsc124f4f2015-09-15 14:41:29 -050056class 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
Brad Bishop6e60e8b2018-02-01 10:27:11 -050080 ud.localfile = d.expand(urllib.parse.unquote(ud.basename))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050081
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
Brad Bishop6e60e8b2018-02-01 10:27:11 -050092 dldir = d.getVar('DL_DIR')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050093 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
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600108 cmd = '%s %s %s %s' % (basecmd, port, remote, lpath)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500109
110 bb.fetch2.check_network_access(d, cmd, ud.url)
111 runfetchcmd(cmd, d)
112 return True