FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
UploadSrvPage.php
1 <?php
2 /***********************************************************
3  Copyright (C) 2008-2014 Hewlett-Packard Development Company, L.P.
4  Copyright (C) 2015, 2018 Siemens AG
5 
6  This program is free software; you can redistribute it and/or
7  modify it under the terms of the GNU General Public License
8  version 2 as published by the Free Software Foundation.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 ***********************************************************/
19 
20 namespace Fossology\UI\Page;
21 
25 
27 {
28  const NAME = 'upload_srv_files';
29  const NAME_PARAM = 'name';
30  const SOURCE_FILES_FIELD = 'sourceFiles';
31 
32  public function __construct()
33  {
34  parent::__construct(self::NAME, array(
35  self::TITLE => _("Upload from Server"),
36  self::MENU_LIST => "Upload::From Server",
37  self::DEPENDENCIES => array("agent_unpack", "showjobs"),
38  self::PERMISSION => Auth::PERM_WRITE
39  ));
40  }
41 
42  function check_if_host_is_allowed($host)
43  {
44  global $SysConf;
45  $sysConfig = $SysConf['SYSCONFIG'];
46  if (array_key_exists('UploadFromServerAllowedHosts', $sysConfig)) {
47  $hostListPre = $sysConfig['UploadFromServerAllowedHosts'];
48  $hostList = explode(':', $hostListPre);
49  } else {
50  $hostList = array("localhost");
51  }
52 
53  return in_array($host,$hostList);
54  }
55 
65  function check_by_whitelist($path)
66  {
67  global $SysConf;
68  $sysConfig = $SysConf['SYSCONFIG'];
69  if (array_key_exists('UploadFromServerWhitelist', $sysConfig)) {
70  $whitelistPre = $sysConfig['UploadFromServerWhitelist'];
71  $whitelist = explode(':', $whitelistPre);
72  } else {
73  $whitelist = array("/tmp");
74  }
75 
76  foreach ($whitelist as $item) {
77  if (substr($path, 0,strlen($item)) === trim($item)) {
78  return true;
79  }
80  }
81  return false;
82  }
83 
93  function remote_file_permission($path, $server = 'localhost', $persmission = 'r')
94  {
98  if ($server === 'localhost' || empty($server)) {
99  $temp_path = str_replace('\ ', ' ', $path); // replace '\ ' with ' '
100  return @fopen($temp_path, $persmission);
101  } else {
102  return 1; // don't do the file permission check if the file is not on the web server
103  }
104  }
105 
114  function remote_file_exists($path, $server = 'localhost')
115  {
119  if ($server === 'localhost' || empty($server)) {
120  $temp_path = str_replace('\ ', ' ', $path); // replace '\ ' with ' '
121  return file_exists($temp_path);
122  } else {
123  return 1; // don't do the file exist check if the file is not on the web server
124  }
125  }
126 
131  protected function handleView(Request $request, $vars)
132  {
133  $vars['sourceFilesField'] = self::SOURCE_FILES_FIELD;
134  $vars['nameField'] = self::NAME_PARAM;
135  $vars['hostlist'] = HostListOption();
136  return $this->render("upload_srv.html.twig", $this->mergeWithDefault($vars));
137  }
138 
142  protected function handleUpload(Request $request)
143  {
144  global $Plugins;
145 
146  define("UPLOAD_ERR_INVALID_FOLDER_PK", 100);
147  define("UPLOAD_ERR_RESEND", 200);
148  $uploadErrors = array(
149  UPLOAD_ERR_INVALID_FOLDER_PK => _("Invalid Folder."),
150  UPLOAD_ERR_RESEND => _("This seems to be a resent file.")
151  );
152 
153  $folderId = intval($request->get(self::FOLDER_PARAMETER_NAME));
154  $description = stripslashes($request->get(self::DESCRIPTION_INPUT_NAME));
155  $description = $this->basicShEscaping($description);
156 
157  if ($request->getSession()->get(self::UPLOAD_FORM_BUILD_PARAMETER_NAME) !=
158  $request->get(self::UPLOAD_FORM_BUILD_PARAMETER_NAME)) {
159  return array(false, $uploadErrors[UPLOAD_ERR_RESEND], $description);
160  }
161 
162  if (empty($folderId)) {
163  return array(false, $uploadErrors[UPLOAD_ERR_INVALID_FOLDER_PK], $description);
164  }
165 
166  $public = $request->get('public');
167  $publicPermission = ($public == self::PUBLIC_ALL) ? Auth::PERM_READ : Auth::PERM_NONE;
168 
169  $sourceFiles = trim($request->get(self::SOURCE_FILES_FIELD));
170  $sourceFiles = $this->basicShEscaping($sourceFiles);
171  $host = $request->get('host') ?: "localhost";
172  if (preg_match('/[^a-z.0-9]/i', $host)) {
173  $text = _("The given host is not valid.");
174  return array(false, $text, $description);
175  }
176  if (! $this->check_if_host_is_allowed($host)) {
177  $text = _("You are not allowed to upload from the chosen host.");
178  return array(false, $text,
179  $description
180  );
181  }
182 
183  $name = $request->get(self::NAME_PARAM);
184 
185  if ((preg_match('/[*?%$]+/', $sourceFiles)) && empty($name)) {
186  $text = _(
187  "The file path contains a wildchar, you must provide a name for the upload.");
188  return array(false, $text, $description);
189  }
190 
191  if (empty($name)) {
192  $name = basename($sourceFiles);
193  }
194  $shortName = $this->basicShEscaping(basename($name));
195  if (empty($shortName)) {
196  $shortName = $name;
197  }
198  if (strcmp($host,"localhost")) {
199  $shortName = $host . ':' . $shortName;
200  }
201 
202  $sourceFiles = $this->normalize_path($sourceFiles,$host);
203  $sourceFiles = str_replace('|', '\|', $sourceFiles);
204  $sourceFiles = str_replace(' ', '\ ', $sourceFiles);
205  $sourceFiles = str_replace("\t", "\\t", $sourceFiles);
206  if ($sourceFiles == FALSE) {
207  $text = _("failed to normalize/validate given path");
208  return array(false, $text, $description);
209  }
210  if ($this->check_by_whitelist($sourceFiles) === FALSE) {
211  $text = _("no suitable prefix found in the whitelist") . ", " .
212  _("you are not allowed to upload this file");
213  return array(false, $text, $description);
214  }
215  if (! $this->path_is_pattern($sourceFiles) &&
216  ! $this->remote_file_exists($sourceFiles, $host)) {
217  $text = _("'$sourceFiles' does not exist.\n");
218  return array(false, $text, $description);
219  }
220  if (! $this->path_is_pattern($sourceFiles) &&
221  ! $this->remote_file_permission($sourceFiles, $host, "r")) {
222  $text = _("Have no READ permission on '$sourceFiles'.\n");
223  return array(false, $text, $description);
224  }
225  if (! $this->path_is_pattern($sourceFiles) && is_file($sourceFiles) &&
226  filesize($sourceFiles) <= 0) {
227  $text = _("You can not upload an empty file.\n");
228  return array(false, $text, $description);
229  }
230 
231  /* Create an upload record. */
232  $uploadMode = (1 << 3); // code for "it came from web upload"
233  $userId = Auth::getUserId();
234  $groupId = Auth::getGroupId();
235  $uploadId = JobAddUpload($userId, $groupId, $shortName, $sourceFiles,
236  $description, $uploadMode, $folderId, $publicPermission);
237 
238  if (empty($uploadId)) {
239  $text = _("Failed to insert upload record");
240  return array(false, $text, $description);
241  }
242 
243  /* Prepare the job: job "wget" */
244  $jobpk = JobAddJob($userId, $groupId, "wget", $uploadId);
245  if (empty($jobpk) || ($jobpk < 0)) {
246  $text = _("Failed to insert upload record");
247  return array(false, $text, $description);
248  }
249 
250  $jq_args = "$uploadId - $sourceFiles";
251 
252  $jobqueuepk = JobQueueAdd($jobpk, "wget_agent", $jq_args, "no", NULL, $host);
253  if (empty($jobqueuepk)) {
254  $text = _("Failed to insert task 'wget' into job queue");
255  return array(false, $text, $description);
256  }
257 
258  $ErrorMsg = "";
259 
260  /* schedule agents */
261  $unpackplugin = &$Plugins[plugin_find_id("agent_unpack")];
262  $unpackArgs = intval($request->get('scm') == 1) ? '-I' : '';
263  $ununpack_jq_pk = $unpackplugin->AgentAdd($jobpk, $uploadId, $ErrorMsg, array("wget_agent"), $unpackargs);
264  if ($ununpack_jq_pk < 0) {
265  return array(false, $text, _($ErrorMsg));
266  }
267 
268  $adj2nestplugin = &$Plugins[plugin_find_id("agent_adj2nest")];
269  $adj2nest_jq_pk = $adj2nestplugin->AgentAdd($jobpk, $uploadId, $ErrorMsg, array());
270  if ($adj2nest_jq_pk < 0) {
271  return array(false, $text, _($ErrorMsg));
272  }
273 
274  AgentCheckBoxDo($jobpk, $uploadId);
275 
276  $message = "";
278  $status = GetRunnableJobList();
279  if (empty($status)) {
280  $message .= _("Is the scheduler running? ");
281  }
282  $Url = Traceback_uri() . "?mod=showjobs&upload=$uploadId";
283  $message .= "The file $sourceFiles has been uploaded. ";
284  $keep = "It is <a href='$Url'>upload #" . $uploadId . "</a>.\n";
285  return array(true, $message.$keep, $description, $uploadId);
286  }
287 }
288 register_plugin(new UploadSrvPage());
GetRunnableJobList()
Get runnable job list, the process is below:
handleUpload(Request $request)
Process the upload request.
Traceback_uri()
Get the URI without query to this location.
static getUserId()
Get the current user&#39;s id.
Definition: Auth.php:69
check_by_whitelist($path)
checks, whether a normalized path starts with an path in the whiteliste
AgentCheckBoxDo($job_pk, $upload_pk)
Assume someone called AgentCheckBoxMake() and submitted the HTML form. Run AgentAdd() for each of the...
normalize_path($path, $host="localhost", $appendix="")
normalizes an path and returns FALSE on errors
render($templateName, $vars=null, $headers=null)
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:159
handleView(Request $request, $vars)
remote_file_permission($path, $server= 'localhost', $persmission= 'r')
chck if one file/dir has one permission
path_is_pattern($path)
checks, whether a path is a pattern from the perspective of a shell
remote_file_exists($path, $server= 'localhost')
chck if one file/dir exist or not
HostListOption()
Get host list.
Definition: common-ui.php:160
static getGroupId()
Get the current user&#39;s group id.
Definition: Auth.php:78
JobAddUpload($userId, $groupId, $job_name, $filename, $desc, $UploadMode, $folder_pk, $public_perm=Auth::PERM_NONE)
Insert a new upload record, and update the foldercontents table.
Definition: common-job.php:66
char * trim(char *ptext)
Trimming whitespace.
Definition: fossconfig.c:695