Commit graph

60 commits

Author SHA1 Message Date
Tim Starling
47a1619027 Remove terminating line breaks from debug messages
A terminating line break has not been required in wfDebug() since 2014,
however no migration was done. Some of these line breaks found their way
into LoggerInterface::debug() calls, where they mess up the formatting
of the debug log.

So, remove terminating line breaks from wfDebug() and
LoggerInterface::debug() calls.

Also:
* Fix the stripping of leading line breaks from the log header emitted
  by Setup.php. This feature, accidentally broken in 2014, allows
  requests to be distinguished in the log file.
* Avoid using the global variable $self.
* Move the logging of the client IP back to Setup.php. It was moved to
  WebRequest in the hopes that it would not always be needed, however
  $wgRequest->getIP() is now called unconditionally a few lines up in
  Setup.php. This means that it is put in its proper place after the
  "start request" message.
* Wrap the log header code in a closure so that variables like $name do
  not leak into global scope.
* In Linker.php, remove a few instances of an unnecessary second
  parameter to wfDebug().

Change-Id: I96651d3044a95b9d210b51cb8368edc76bebbb9e
2020-06-03 12:01:16 +10:00
Tim Starling
68c433bd23 Hooks::run() call site migration
Migrate all callers of Hooks::run() to use the new
HookContainer/HookRunner system.

General principles:
* Use DI if it is already used. We're not changing the way state is
  managed in this patch.
* HookContainer is always injected, not HookRunner. HookContainer
  is a service, it's a more generic interface, it is the only
  thing that provides isRegistered() which is needed in some cases,
  and a HookRunner can be efficiently constructed from it
  (confirmed by benchmark). Because HookContainer is needed
  for object construction, it is also needed by all factories.
* "Ask your friendly local base class". Big hierarchies like
  SpecialPage and ApiBase have getHookContainer() and getHookRunner()
  methods in the base class, and classes that extend that base class
  are not expected to know or care where the base class gets its
  HookContainer from.
* ProtectedHookAccessorTrait provides protected getHookContainer() and
  getHookRunner() methods, getting them from the global service
  container. The point of this is to ease migration to DI by ensuring
  that call sites ask their local friendly base class rather than
  getting a HookRunner from the service container directly.
* Private $this->hookRunner. In some smaller classes where accessor
  methods did not seem warranted, there is a private HookRunner property
  which is accessed directly. Very rarely (two cases), there is a
  protected property, for consistency with code that conventionally
  assumes protected=private, but in cases where the class might actually
  be overridden, a protected accessor is preferred over a protected
  property.
* The last resort: Hooks::runner(). Mostly for static, file-scope and
  global code. In a few cases it was used for objects with broken
  construction schemes, out of horror or laziness.

Constructors with new required arguments:
* AuthManager
* BadFileLookup
* BlockManager
* ClassicInterwikiLookup
* ContentHandlerFactory
* ContentSecurityPolicy
* DefaultOptionsManager
* DerivedPageDataUpdater
* FullSearchResultWidget
* HtmlCacheUpdater
* LanguageFactory
* LanguageNameUtils
* LinkRenderer
* LinkRendererFactory
* LocalisationCache
* MagicWordFactory
* MessageCache
* NamespaceInfo
* PageEditStash
* PageHandlerFactory
* PageUpdater
* ParserFactory
* PermissionManager
* RevisionStore
* RevisionStoreFactory
* SearchEngineConfig
* SearchEngineFactory
* SearchFormWidget
* SearchNearMatcher
* SessionBackend
* SpecialPageFactory
* UserNameUtils
* UserOptionsManager
* WatchedItemQueryService
* WatchedItemStore

Constructors with new optional arguments:
* DefaultPreferencesFactory
* Language
* LinkHolderArray
* MovePage
* Parser
* ParserCache
* PasswordReset
* Router

setHookContainer() now required after construction:
* AuthenticationProvider
* ResourceLoaderModule
* SearchEngine

Change-Id: Id442b0dbe43aba84bd5cf801d86dedc768b082c7
2020-05-30 14:23:28 +00:00
Tim Starling
0b7295a5cd Hook interface doc comment followup
Mostly just narrower array types. A handful of other errors fixed.

Change-Id: Ied79d9e389867911bf83696dbb47f43305f8be7b
2020-04-21 09:12:23 +10:00
apaskulin
c44488f725 docs: Hook interface doc comment review
Edited doc comments for hook interfaces to improve
consistency and add type hints.

Bug: T246855
Change-Id: I38fa802463cd6f39bf5946dbbeb1b3ebaea604b2
2020-04-21 09:10:08 +10:00
Tim Starling
f5aaf75ad1 Automatically generated hook interfaces
Add hook interfaces which were generated by a script which parses
hooks.txt and identifies caller namespaces and directories.

Hook interfaces are mostly placed in a Hook/ subdirectory
relative to the caller location. When there are callers in multiple
directories, a "primary" caller was manually selected. The exceptions to
this are:

* The source root, maintenance and tests, which use includes/Hook. Test
  hooks need to be autoloadable in a non-test request so that
  implementing test interfaces in a generic handler will not fail.
* resources uses includes/resourceloader/Hook
* The following third-level subdirectories had their hooks placed in
  the parent ../Hook:
    * includes/filerepo/file
    * includes/search/searchwidgets
    * includes/specials/forms
    * includes/specials/helpers
    * includes/specials/pagers

Parameters marked as legacy references in hooks.txt are passed
by value in the interfaces.

Bug: T240307
Change-Id: I6efe2e7dd1f0c6a3d0f4d100a4c34e41f8428720
2020-04-20 13:31:05 +10:00
Thiemo Kreuz
1006aa41e6 Fix mismatching type hints in PHPDoc tags
This is a collection of random bits from my local stashes. This patch
intentionally only touches comments, no code.

Notably:
* Use more specific string[] instead of array, if possible.
* Some comments mention "or null", but miss to list the type.

Change-Id: I712b28964f125c8e3dcb4e3fb993757a09f96644
2020-03-24 09:59:02 +01:00
James D. Forrester
0958a0bce4 Coding style: Auto-fix MediaWiki.Usage.IsNull.IsNull
Change-Id: I90cfe8366c0245c9c67e598d17800684897a4e27
2020-01-10 14:17:13 -08:00
Max Semenik
3f94708eff Shell: Add more types
Change-Id: I315f0bb2746ccf7249b8d622a153162dd634ff2e
2019-10-31 01:16:35 +00:00
Max Semenik
d2d99b9a59 Shell\Result: declare types, enable strict types
This is a very limited value class created in just one place, so it
looks like a good candidate for experimenting with strict types.

Change-Id: I777c713f8b3be6688c327f7e6fcf97cc9b7ab66e
2019-10-30 17:58:23 -07:00
Max Semenik
949778ec87 Shell: Declare constants visibility
Change-Id: Ic1285b34fe8ef3efd3d5515e917f4fad7494b9a2
2019-10-28 21:31:33 -07:00
Max Semenik
e5192f32bb shell: Resolve a TODO asking for error_clear_last()
Bug: T103671
Change-Id: I15c95962b198a0b46631c4d9a1b8fb55f37ae949
2019-10-02 21:38:09 -07:00
Daimona Eaytoy
b5cbb5ab3f Upgrade phan config to 0.7.1
This allows us to remove many suppressions for phan false positives.

Bug: T231636
Depends-On: I82a279e1f7b0fdefd3bb712e46c7d0665429d065
Change-Id: I5c251e9584a1ae9fb1577afcafb5001e0dcd41c7
2019-09-04 08:20:53 +00:00
Daimona Eaytoy
327e8ea416 Unsuppress phan issues part 6
Bug: T231636
Depends-On: I50377746f01749b058c39fd8229f9d566224cc43
Change-Id: I2cd24e73726394e3200a570c45d5e86b6849bfa9
2019-09-01 09:48:45 +00:00
Daimona Eaytoy
5eac6d131c Unsuppress more phan issues (part 3)
Bug: T231636
Depends-On: I78354bf5f0c831108c8f606e50c87cf6bc00d8bd
Change-Id: I58e67c2b38389df874438deada4239510d21654f
2019-08-31 16:38:55 +00:00
Derick Alangi
3cfe00b736 Avoid the use of silence operator (@) and use AtEase methods
Bug: T26159
Change-Id: I973cc607fd909d47faf2773a02835af83bbc301f
2019-07-23 08:43:44 +01:00
Derick Alangi
cfb9ddc78d shell: Remove documentation that doesn't add meaning to the method
Change-Id: I924453f683f058586516bb12e54940449d29cfd9
2019-06-17 17:40:37 +01:00
Reedy
0517b9af9b Update wikimedia/at-ease from 1.2.0 to 2.0.0
https://github.com/wikimedia/at-ease/releases/tag/v2.0.0
https://github.com/wikimedia/at-ease/compare/v1.2.0...v2.0.0

Change-Id: Ia49a156e76d0a4e257e91cc6a51050848bcb9a5e
Depends-On: If40364e2590e3c23035838f8ed26c4f69e730602
2019-05-18 14:32:57 +01:00
Max Semenik
e7d13e88b8 shell: annotate return types
Change-Id: I3ab0a6409088c86581d9d50a340e82b0ea354814
2019-04-26 13:54:41 -07:00
Aryeh Gregor
7b4489e019 Get rid of unnecessary func_get_args() and friends
HHVM does not support variadic arguments with type hints.  This is
mostly not a big problem, because we can just drop the type hint, but
for some reason PHPUnit adds a type hint of "array" when it creates
mocks, so a class with a variadic method can't be mocked (at least in
some cases).  As such, I left alone all the classes that seem like
someone might like to mock them, like Title and User.  If anyone wants
to mock them in the future, they'll have to switch back to
func_get_args().  Some of the changes are definitely safe, like
functions and test classes.

In most cases, func_get_args() (and/or func_get_arg(), func_num_args() )
were only present because the code was written before we required PHP
5.6, and writing them as variadic functions is strictly superior. In
some cases I left them alone, aside from HHVM compatibility:

* Forwarding all arguments to another function. It's useful to keep
  func_get_args() here where we want to keep the list of expected
  arguments and their meanings in the function signature line for
  documentation purposes, but don't want to copy-paste a long line of
  argument names.
* Handling deprecated calling conventions.
* One or two miscellaneous cases where we're basically using the
  arguments individually but want to use them as an array as well for
  some reason.

Change-Id: I066ec95a7beb7c0665146195a08e7cce1222c788
2019-04-12 20:17:01 +00:00
Fomafix
9cbb8f104d Use https://www.php.net/ instead of https://secure.php.net/
Change-Id: I0acca592c6909e91b28b904da49dcbd6a43cd2a5
2019-04-12 06:44:48 +02:00
Reedy
daf15e14ab Update AtEase calls to use Wikimedia namespace
Helps ease migration (stops vendor patch failing)

Change-Id: I9a985b341e1c3664c4ced6f793b19149067a580a
2019-02-12 23:48:31 +00:00
Max Semenik
f735507bfc Convert RandomImageGenerator to use the new execution framework
Introduces a stringifier for Command, useful for debugging.

Change-Id: Ifcfccaef5a609e0cf30186e39a6bd0fa971c2dbd
2019-01-21 22:33:02 -08:00
D3r1ck01
0770f85a0a Merge "Use MediaWiki\SuppressWarnings around trigger_error('') instead @" 2018-12-19 17:15:17 +00:00
Fomafix
43244db9a2 Use PHP 7 '??' operator instead of if-then-else
Change-Id: If9d4be5d88c8927f63cbb84dfc8181baf62ea3eb
2018-10-21 21:46:46 +02:00
Max Semenik
9b0c621d7f Deprecate wfArrayFilter() and wfArrayFilterByKey()
Now that all our supported PHP versions have array_filter()
with a third parameter, these functions aren't needed anymore.

Depends-On: I3b097a1a048baabcaca15dc214a3a1bb06e746cc
Depends-On: I0187e27ac47cbab099249572201d1a649226a734
Change-Id: I7cabd0252691a083cb749cf9d3a7a23f1d076c39
2018-07-19 08:40:46 +02:00
Kunal Mehta
83524ae39a shell: Note that ::isDisabled() should be called before ::command()
And check it in the FirejailCommandTest (integration) for completeness,
even though it will make no practical difference.

Change-Id: Ieb130a888ef8a8162cb0a049ab9c20eac3f58217
2018-07-02 22:16:03 +00:00
Max Semenik
817049ec6b Begin introducing PHP 5.6 variadic parameters where appropriate
Change-Id: I5670b8482e8d3bcb0b3a2b4d2ce9834cfc37e171
2018-06-04 11:53:55 -07:00
jenkins-bot
a9d9f196de Merge "Use PHP7 constant expression instead of a magic number" 2018-05-31 19:21:32 +00:00
Max Semenik
657a6b2497 Use PHP7 constant expression instead of a magic number
Change-Id: I84e13dc6019c429359df3395f0731d17859be06c
2018-05-30 19:43:04 -07:00
Bartosz Dziewoński
485f66f174 Use PHP 7 '??' operator instead of '?:' with 'isset()' where convenient
Find: /isset\(\s*([^()]+?)\s*\)\s*\?\s*\1\s*:\s*/
Replace with: '\1 ?? '

(Everywhere except includes/PHPVersionCheck.php)
(Then, manually fix some line length and indentation issues)

Then manually reviewed the replacements for cases where confusing
operator precedence would result in incorrect results
(fixing those in I478db046a1cc162c6767003ce45c9b56270f3372).

Change-Id: I33b421c8cb11cdd4ce896488c9ff5313f03a38cf
2018-05-30 18:06:13 -07:00
Fomafix
d65ac78277 Replace HTTP by HTTPS
* https://www.unicode.org/ instead of http://www.unicode.org/ or
  http://unicode.org/
* https://secure.php.net/ instead of http://www.php.net/ or
  http://php.net/
* https://hhvm.com/ instead of http://hhvm.com/
* https://www.iis.net/ instead of http://www.iis.net/

Change-Id: I84d818a7e0ced5ffb9485ec89a75efb28a77c1e0
2018-05-22 12:14:14 +02:00
Mark A. Hershberger
d68806c03b Use MediaWiki\SuppressWarnings around trigger_error('') instead @
The @ sign requires a phpcs:ignore.

\MediaWiki\suppressWarnings() doesn't need a phpcs:ignore.

Bug: T191247
Change-Id: I6ef1e706f4f2a4192dde7a668b3b97086a4a8a68
2018-04-17 16:34:00 +00:00
Max Semenik
efa586fddd Restrict shell commands by default
Before it's too late, let's boil the oceans
and just do it. This patch assumes that old code
calling wfShellExec() doesn't know about restrictions
so it doesn't restrict anything. New code, however,
needs to specify its restrictions or deal with defaults.

Change-Id: I58963901087202d4a405bcdb6bd12758bb6b0ff7
2018-04-16 11:50:13 -07:00
Max Semenik
5cf4575ea3 Deprecate wfShellWikiCmd()
Bug: T184339

Change-Id: Ic86a451e0e9d609e06865a4969560d151efa844c
2018-04-16 16:38:05 +00:00
Kunal Mehta
a44c2b62ca shell: Don't use --seccomp=@default for firejail < 0.9.50 support
Just using a plain `--seccomp` automatically enables the default list.

Bug: T183680
Change-Id: I623db943eeb5c3e9d4f7a553fb6a17a60d659dce
2018-02-26 14:11:42 -08:00
Brad Jorsch
86cfcfdbba Shell: Don't hang on empty stdin
If the write buffer for a file descriptor is empty, don't try to write
to it. Just close it and continue on.

Bug: T188019
Change-Id: Ie5b5ac1ef1aec4ae763cf4d0d58d3a28e42b7d2a
2018-02-22 17:13:28 -05:00
Brad Jorsch
38bf4c1521 Shell: Set pipes to non-blocking
The select(2) system call only guarantees a "sufficiently small write"
can be made without blocking. It doesn't define what that means.

And on Linux the read might block too in certain cases, although I don't
know if any of them can occur here.

Regardless, set all the pipes to non-blocking, which avoids the blocking
that's behind T184171.

And then, since a non-blocking read might validly return empty-string or
a non-blocking write might validly return 0, use feof() to check for EOF
and actually close the write pipe when it runs out of data.

Bug: T184171
Change-Id: I403235a328630112b6920905730f933777e2d453
2018-02-01 16:04:12 -05:00
Umherirrender
23ef520a1c Improve some parameter docs
Change-Id: I31e983d7ac287158101b18ad95779d83537302a2
2018-01-07 11:39:08 +01:00
Gergő Tisza
0e211c4f29 Allow programmatic input in Command
Bug: T182463
Change-Id: Ib68180c7af12558686f4864c24fd85f01201d6fb
2018-01-03 19:53:47 +03:00
Umherirrender
255d76f2a1 build: Updating mediawiki/mediawiki-codesniffer to 15.0.0
Clean up use of @codingStandardsIgnore
- @codingStandardsIgnoreFile -> phpcs:ignoreFile
- @codingStandardsIgnoreLine -> phpcs:ignore
- @codingStandardsIgnoreStart -> phpcs:disable
- @codingStandardsIgnoreEnd -> phpcs:enable

For phpcs:disable always the necessary sniffs are provided.
Some start/end pairs are changed to line ignore

Change-Id: I92ef235849bcc349c69e53504e664a155dd162c8
2018-01-01 14:10:16 +01:00
jenkins-bot
983173f3be Merge "shell: Add NO_LOCALSETTINGS restriction" 2017-12-22 01:44:22 +00:00
Kunal Mehta
59dfe57b92 shell: Add debug logging to find binaries that aren't being restricted
Assume the first part of the command is the binary, and include it directly
in the message to make grouping work on a per-binary basis. Includ the rest
of the params as log context just in case it is useful.

Change-Id: Ibfff7b1fee083efffae833b9bfa71ae9806c1bbd
2017-12-11 16:25:33 -08:00
Kunal Mehta
416975c3ac shell: Run firejail inside limit.sh, make NO_EXECVE work
NO_EXECVE doesn't work because limit.sh needs to execute the main
command, and does so through the execve syscall. Eventually we should be
able to replace limit.sh with firejail functionality entirely (T179021),
but in the meantime we can run firejail inside limit.sh.

We also need to stop firejail from running the command in a bash shell
via --shell=none, since that shell would also use the execve syscall.

Bug: T182489
Change-Id: I3fc8ad2f9e5eb5bf13b49d0bccd6094668a5ec55
2017-12-09 04:07:32 -08:00
Kunal Mehta
1476429857 shell: Add NO_LOCALSETTINGS restriction
Most secret information like database passwords are kept in LocalSettings.php,
so blacklisting that file by default would take away a lot of information an
attacker would want.

Since most commands shouldn't need to read the PHP configuration, add it to
RESTRICT_DEFAULT. People can still use:
 $cmd->restrict( Shell::RESTRICT_DEFAULT & ~Shell::NO_LOCALSETTINGS );

if they need to still access LocalSettings.php

Bug: T182484
Change-Id: I4032e2706e808e9b819e92a06eff536ccf043388
2017-12-08 22:05:14 -08:00
Max Semenik
36009e3ca7 Shell: skip null parameters
Right now they're treated as empty strings, however
this doesn't allow skipping parameters in the middle like
 $params = [
     'foo',
     $x ? '--bar' : null,
     '--baz',
 ];

In some cases this matters, e.g. `ls` works while `ls ''` doesn't.

Also, fix spacing problems the new tests uncovered:
* Extra space when using params()
* Missing space when combining params() and unsafeParams()

Change-Id: Icb29d4c48ae7f92fb5635e3865346c98f47abb01
2017-11-29 12:38:35 -08:00
Kunal Mehta
bdb5b592f4 shell: Optionally restrict commands' access with firejail
Introduces a FirejailCommand class, which can be used to add additional
restrictions to a command, for increased security. For now, firejail
containment needs to be enabled on a per-command basis.

The following restrictions are implemented:
* NO_ROOT - disallows any root access, including via setuid binaries
* SECCOMP - block dangerous syscalls with seccomp
* PRIVATE_DEV - create a private /dev
* NO_NETWORK - deny all network access
* NO_EXECVE - block the execve syscall

A convenient Shell::RESTRICT_DEFAULT is equivalent to NO_ROOT | SECCOMP
| PRIVATE_DEV, with the expectation that more restrictions may be added
to it in the future.

In addition, specific paths can be whitelisted with
Command::whitelistPaths(). Any file/directory that isn't whitelisted in
that top level directory (e.g. /srv) won't exist inside the firejail.

$wgShellRestrictionMethod can be set to false for no restriction system,
'firejail' to explicitly use it, or 'autodetect' to autodetect whatever
system is available. In the future the default should be changed to
autodetection once firejail is tested more.

Bug: T173370
Change-Id: Id74df0dbba40e1e7c07c4368aacffb6eb06a17c5
2017-11-28 00:06:40 +00:00
Gergő Tisza
7d9dbc0040
MediaWiki\Shell: log stderr
Change-Id: I1495fe2aba10102d7e36c3a3e5fdabf97f14546b
2017-10-26 21:06:03 -07:00
Umherirrender
9aa56950c2 Remove @codingStandardsIgnore from long lines
Breaks some line where the ignore is not needed.

The sniff was changed upstream to be okay
with long unbreakable lines in comments

Change-Id: I2bbe2be7cedd4d3c0ce8dc3e62d0e268bc171876
2017-10-22 16:44:04 +02:00
Kunal Mehta
c3bbadcc83 Shell\Command: Move code that builds final shell command into separate method
Change-Id: I6aae209fd0b20057b5f7f7129db92c184ec945f8
2017-10-19 19:38:42 -07:00
Max Semenik
32912b8c8d Introduce Shell\CommandFactory
Bug: T177038
Change-Id: Id875e68ea1fa72b44a463f977ab52270fe1e7088
2017-10-17 18:55:11 -07:00