FOSSology  4.4.0
Open Source License Compliance by Open Source Software
UploadSrvPage.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2008-2014 Hewlett-Packard Development Company, L.P.
4  SPDX-FileCopyrightText: © 2015, 2018 Siemens AG
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
8 
9 namespace Fossology\UI\Page;
10 
13 use Symfony\Component\HttpFoundation\Request;
14 
16 {
17  const NAME = 'upload_srv_files';
18  const NAME_PARAM = 'name';
19  const SOURCE_FILES_FIELD = 'sourceFiles';
20 
21  public function __construct()
22  {
23  parent::__construct(self::NAME, array(
24  self::TITLE => _("Upload from Server"),
25  self::MENU_LIST => "Upload::From Server",
26  self::DEPENDENCIES => array("agent_unpack", "showjobs"),
27  self::PERMISSION => Auth::PERM_WRITE
28  ));
29  }
30 
31  function check_if_host_is_allowed($host)
32  {
33  global $SysConf;
34  $sysConfig = $SysConf['SYSCONFIG'];
35  if (array_key_exists('UploadFromServerAllowedHosts', $sysConfig)) {
36  $hostListPre = $sysConfig['UploadFromServerAllowedHosts'];
37  $hostList = explode(':', $hostListPre);
38  } else {
39  $hostList = array("localhost");
40  }
41 
42  return in_array($host,$hostList);
43  }
44 
54  function check_by_whitelist($path)
55  {
56  global $SysConf;
57  $sysConfig = $SysConf['SYSCONFIG'];
58  if (array_key_exists('UploadFromServerWhitelist', $sysConfig)) {
59  $whitelistPre = $sysConfig['UploadFromServerWhitelist'];
60  $whitelist = explode(':', $whitelistPre);
61  } else {
62  $whitelist = array("/tmp");
63  }
64 
65  foreach ($whitelist as $item) {
66  if (substr($path, 0,strlen($item)) === trim($item)) {
67  return true;
68  }
69  }
70  return false;
71  }
72 
82  function remote_file_permission($path, $server = 'localhost', $persmission = 'r')
83  {
87  if ($server === 'localhost' || empty($server)) {
88  $temp_path = str_replace('\ ', ' ', $path); // replace '\ ' with ' '
89  return @fopen($temp_path, $persmission);
90  } else {
91  return 1; // don't do the file permission check if the file is not on the web server
92  }
93  }
94 
103  function remote_file_exists($path, $server = 'localhost')
104  {
108  if ($server === 'localhost' || empty($server)) {
109  $temp_path = str_replace('\ ', ' ', $path); // replace '\ ' with ' '
110  return file_exists($temp_path);
111  } else {
112  return 1; // don't do the file exist check if the file is not on the web server
113  }
114  }
115 
121  protected function handleView(Request $request, $vars)
122  {
123  $vars['sourceFilesField'] = self::SOURCE_FILES_FIELD;
124  $vars['nameField'] = self::NAME_PARAM;
125  $vars['hostlist'] = HostListOption();
126  return $this->render("upload_srv.html.twig", $this->mergeWithDefault($vars));
127  }
128 
132  protected function handleUpload(Request $request)
133  {
134  global $Plugins;
135 
136  define("UPLOAD_ERR_INVALID_FOLDER_PK", 100);
137  define("UPLOAD_ERR_RESEND", 200);
138  $uploadErrors = array(
139  UPLOAD_ERR_INVALID_FOLDER_PK => _("Invalid Folder."),
140  UPLOAD_ERR_RESEND => _("This seems to be a resent file.")
141  );
142 
143  $folderId = intval($request->get(self::FOLDER_PARAMETER_NAME));
144  $description = stripslashes($request->get(self::DESCRIPTION_INPUT_NAME));
145  $description = $this->basicShEscaping($description);
146 
147  if ($request->getSession()->get(self::UPLOAD_FORM_BUILD_PARAMETER_NAME) !=
148  $request->get(self::UPLOAD_FORM_BUILD_PARAMETER_NAME)) {
149  return array(false, $uploadErrors[UPLOAD_ERR_RESEND], $description);
150  }
151 
152  if (empty($folderId)) {
153  return array(false, $uploadErrors[UPLOAD_ERR_INVALID_FOLDER_PK], $description);
154  }
155 
156  $setGlobal = ($request->get('globalDecisions')) ? 1 : 0;
157 
158  $public = $request->get('public');
159  $publicPermission = ($public == self::PUBLIC_ALL) ? Auth::PERM_READ : Auth::PERM_NONE;
160 
161  $sourceFiles = trim($request->get(self::SOURCE_FILES_FIELD));
162  $sourceFiles = $this->basicShEscaping($sourceFiles);
163  $host = $request->get('host') ?: "localhost";
164  if (preg_match('/[^a-z.0-9]/i', $host)) {
165  $text = _("The given host is not valid.");
166  return array(false, $text, $description);
167  }
168  if (! $this->check_if_host_is_allowed($host)) {
169  $text = _("You are not allowed to upload from the chosen host.");
170  return array(false, $text,
171  $description
172  );
173  }
174 
175  $name = $request->get(self::NAME_PARAM);
176 
177  if ((preg_match('/[*?%$]+/', $sourceFiles)) && empty($name)) {
178  $text = _(
179  "The file path contains a wildchar, you must provide a name for the upload.");
180  return array(false, $text, $description);
181  }
182 
183  if (empty($name)) {
184  $name = basename($sourceFiles);
185  }
186  $shortName = $this->basicShEscaping(basename($name));
187  if (empty($shortName)) {
188  $shortName = $name;
189  }
190  if (strcmp($host,"localhost")) {
191  $shortName = $host . ':' . $shortName;
192  }
193 
194  $sourceFiles = $this->normalize_path($sourceFiles,$host);
195  $sourceFiles = str_replace('|', '\|', $sourceFiles);
196  $sourceFiles = str_replace(' ', '\ ', $sourceFiles);
197  $sourceFiles = str_replace("\t", "\\t", $sourceFiles);
198  if ($sourceFiles == FALSE) {
199  $text = _("failed to normalize/validate given path");
200  return array(false, $text, $description);
201  }
202  if ($this->check_by_whitelist($sourceFiles) === FALSE) {
203  $text = _("no suitable prefix found in the whitelist") . ", " .
204  _("you are not allowed to upload this file");
205  return array(false, $text, $description);
206  }
207  if (! $this->path_is_pattern($sourceFiles) &&
208  ! $this->remote_file_exists($sourceFiles, $host)) {
209  $text = _("'$sourceFiles' does not exist.\n");
210  return array(false, $text, $description);
211  }
212  if (! $this->path_is_pattern($sourceFiles) &&
213  ! $this->remote_file_permission($sourceFiles, $host, "r")) {
214  $text = _("Have no READ permission on '$sourceFiles'.\n");
215  return array(false, $text, $description);
216  }
217  if (! $this->path_is_pattern($sourceFiles) && is_file($sourceFiles) &&
218  filesize($sourceFiles) <= 0) {
219  $text = _("You can not upload an empty file.\n");
220  return array(false, $text, $description);
221  }
222 
223  /* Create an upload record. */
224  $uploadMode = (1 << 3); // code for "it came from web upload"
225  $userId = Auth::getUserId();
226  $groupId = Auth::getGroupId();
227  $uploadId = JobAddUpload($userId, $groupId, $shortName, $sourceFiles,
228  $description, $uploadMode, $folderId, $publicPermission, $setGlobal);
229 
230  if (empty($uploadId)) {
231  $text = _("Failed to insert upload record");
232  return array(false, $text, $description);
233  }
234 
235  /* Prepare the job: job "wget" */
236  $jobpk = JobAddJob($userId, $groupId, "wget", $uploadId);
237  if (empty($jobpk) || ($jobpk < 0)) {
238  $text = _("Failed to insert upload record");
239  return array(false, $text, $description);
240  }
241 
242  $jq_args = "$uploadId - $sourceFiles";
243 
244  $jobqueuepk = JobQueueAdd($jobpk, "wget_agent", $jq_args, "no", NULL, $host);
245  if (empty($jobqueuepk)) {
246  $text = _("Failed to insert task 'wget' into job queue");
247  return array(false, $text, $description);
248  }
249 
250  $ErrorMsg = "";
251 
252  /* schedule agents */
253  $unpackplugin = &$Plugins[plugin_find_id("agent_unpack")];
254  $unpackargs = intval($request->get('scm') == 1) ? '-I' : '';
255  $ununpack_jq_pk = $unpackplugin->AgentAdd($jobpk, $uploadId, $ErrorMsg, array("wget_agent"), $unpackargs);
256  if ($ununpack_jq_pk < 0) {
257  return array(false, $text, _($ErrorMsg));
258  }
259 
260  $adj2nestplugin = &$Plugins[plugin_find_id("agent_adj2nest")];
261  $adj2nest_jq_pk = $adj2nestplugin->AgentAdd($jobpk, $uploadId, $ErrorMsg, array());
262  if ($adj2nest_jq_pk < 0) {
263  return array(false, $text, _($ErrorMsg));
264  }
265 
266  $message = $this->postUploadAddJobs($request, $Name, $uploadId, $jobpk);
267  return array(true, $message.$keep, $description, $uploadId);
268  }
269 }
270 register_plugin(new UploadSrvPage());
Contains the constants and helpers for authentication of user.
Definition: Auth.php:24
static getUserId()
Get the current user's id.
Definition: Auth.php:68
static getGroupId()
Get the current user's group id.
Definition: Auth.php:80
render($templateName, $vars=null, $headers=null)
path_is_pattern($path)
checks, whether a path is a pattern from the perspective of a shell
normalize_path($path, $host="localhost", $appendix="")
normalizes an path and returns FALSE on errors
check_by_whitelist($path)
checks, whether a normalized path starts with an path in the whiteliste
handleView(Request $request, $vars)
handleUpload(Request $request)
Process the upload request.
remote_file_permission($path, $server='localhost', $persmission='r')
chck if one file/dir has one permission
remote_file_exists($path, $server='localhost')
chck if one file/dir exist or not
JobQueueAdd($job_pk, $jq_type, $jq_args, $jq_runonpfile, $Depends, $host=NULL, $jq_cmd_args=NULL)
Insert a jobqueue + jobdepends records.
Definition: common-job.php:157
JobAddUpload($userId, $groupId, $job_name, $filename, $desc, $UploadMode, $folder_pk, $public_perm=Auth::PERM_NONE, $setGlobal=0)
Insert a new upload record, and update the foldercontents table.
Definition: common-job.php:56
HostListOption()
Get host list.
Definition: common-ui.php:174
char * trim(char *ptext)
Trimming whitespace.
Definition: fossconfig.c:690