2011-07-22 10:17:57 -07:00
|
|
|
<?php
|
|
|
|
|
2015-01-02 15:20:08 +11:00
|
|
|
final class PhabricatorSSHKeysSettingsPanel extends PhabricatorSettingsPanel {
|
2011-07-22 10:17:57 -07:00
|
|
|
|
2016-06-05 12:38:04 -07:00
|
|
|
public function isManagementPanel() {
|
|
|
|
if ($this->getUser()->getIsMailingList()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-04-02 12:06:05 -07:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-08-13 12:37:26 -07:00
|
|
|
public function getPanelKey() {
|
|
|
|
return 'ssh';
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getPanelName() {
|
|
|
|
return pht('SSH Public Keys');
|
|
|
|
}
|
2011-07-22 10:17:57 -07:00
|
|
|
|
2019-01-21 10:31:23 -08:00
|
|
|
public function getPanelMenuIcon() {
|
|
|
|
return 'fa-file-text-o';
|
|
|
|
}
|
|
|
|
|
2016-06-03 05:31:33 -07:00
|
|
|
public function getPanelGroupKey() {
|
|
|
|
return PhabricatorSettingsAuthenticationPanelGroup::PANELGROUPKEY;
|
2012-08-13 12:37:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
public function processRequest(AphrontRequest $request) {
|
2014-04-02 12:06:05 -07:00
|
|
|
$user = $this->getUser();
|
|
|
|
$viewer = $request->getUser();
|
2011-07-22 10:17:57 -07:00
|
|
|
|
Add a query/policy layer on top of SSH keys for Almanac
Summary:
Ref T5833. Currently, SSH keys are associated only with users, and are a bit un-modern. I want to let Almanac Devices have SSH keys so devices in a cluster can identify to one another.
For example, with hosted installs, initialization will go something like this:
- A request comes in for `company.phacility.com`.
- A SiteSource (from D10787) makes a Conduit call to Almanac on the master install to check if `company` is a valid install and pull config if it is.
- This call can be signed with an SSH key which identifies a trusted Almanac Device.
In the cluster case, a web host can make an authenticated call to a repository host with similar key signing.
To move toward this, put a proper Query class on top of SSH key access (this diff). In following diffs, I'll:
- Rename `userPHID` to `objectPHID`.
- Move this to the `auth` database.
- Provide UI for device/key association.
An alternative approach would be to build some kind of special token layer in Conduit, but I think that would be a lot harder to manage in the hosting case. This gives us a more direct attack on trusting requests from machines and recognizing machines as first (well, sort of second-class) actors without needing things like fake user accounts.
Test Plan:
- Added and removed SSH keys.
- Added and removed SSH keys from a bot account.
- Tried to edit an unonwned SSH key (denied).
- Ran `bin/ssh-auth`, got sensible output.
- Ran `bin/ssh-auth-key`, got sensible output.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T5833
Differential Revision: https://secure.phabricator.com/D10790
2014-11-06 12:37:02 -08:00
|
|
|
$keys = id(new PhabricatorAuthSSHKeyQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withObjectPHIDs(array($user->getPHID()))
|
Deactivate SSH keys instead of destroying them completely
Summary:
Ref T10917. Currently, when you delete an SSH key, we really truly delete it forever.
This isn't very consistent with other applications, but we built this stuff a long time ago before we were as rigorous about retaining data and making it auditable.
In partiular, destroying data isn't good for auditing after security issues, since it means we can't show you logs of any changes an attacker might have made to your keys.
To prepare to improve this, stop destoying data. This will allow later changes to become transaction-oriented and show normal transaction logs.
The tricky part here is that we have a `UNIQUE KEY` on the public key part of the key.
Instead, I changed this to `UNIQUE (key, isActive)`, where `isActive` is a nullable boolean column. This works because MySQL does not enforce "unique" if part of the key is `NULL`.
So you can't have two rows with `("A", 1)`, but you can have as many rows as you want with `("A", null)`. This lets us keep the "each key may only be active for one user/object" rule without requiring us to delete any data.
Test Plan:
- Ran schema changes.
- Viewed public keys.
- Tried to add a duplicate key, got rejected (already associated with another object).
- Deleted SSH key.
- Verified that the key was no longer actually deleted from the database, just marked inactive (in future changes, I'll update the UI to be more clear about this).
- Uploaded a new copy of the same public key, worked fine (no duplicate key rejection).
- Tried to upload yet another copy, got rejected.
- Generated a new keypair.
- Tried to upload a duplicate to an Almanac device, got rejected.
- Generated a new pair for a device.
- Trusted a device key.
- Untrusted a device key.
- "Deleted" a device key.
- Tried to trust a deleted device key, got "inactive" message.
- Ran `bin/ssh-auth`, got good output with unique keys.
- Ran `cat ~/.ssh/id_rsa.pub | ./bin/ssh-auth-key`, got good output with one key.
- Used `auth.querypublickeys` Conduit method to query keys, got good active keys.
Reviewers: chad
Reviewed By: chad
Maniphest Tasks: T10917
Differential Revision: https://secure.phabricator.com/D15943
2016-05-18 09:32:50 -07:00
|
|
|
->withIsActive(true)
|
Add a query/policy layer on top of SSH keys for Almanac
Summary:
Ref T5833. Currently, SSH keys are associated only with users, and are a bit un-modern. I want to let Almanac Devices have SSH keys so devices in a cluster can identify to one another.
For example, with hosted installs, initialization will go something like this:
- A request comes in for `company.phacility.com`.
- A SiteSource (from D10787) makes a Conduit call to Almanac on the master install to check if `company` is a valid install and pull config if it is.
- This call can be signed with an SSH key which identifies a trusted Almanac Device.
In the cluster case, a web host can make an authenticated call to a repository host with similar key signing.
To move toward this, put a proper Query class on top of SSH key access (this diff). In following diffs, I'll:
- Rename `userPHID` to `objectPHID`.
- Move this to the `auth` database.
- Provide UI for device/key association.
An alternative approach would be to build some kind of special token layer in Conduit, but I think that would be a lot harder to manage in the hosting case. This gives us a more direct attack on trusting requests from machines and recognizing machines as first (well, sort of second-class) actors without needing things like fake user accounts.
Test Plan:
- Added and removed SSH keys.
- Added and removed SSH keys from a bot account.
- Tried to edit an unonwned SSH key (denied).
- Ran `bin/ssh-auth`, got sensible output.
- Ran `bin/ssh-auth-key`, got sensible output.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley
Maniphest Tasks: T5833
Differential Revision: https://secure.phabricator.com/D10790
2014-11-06 12:37:02 -08:00
|
|
|
->execute();
|
2011-07-22 10:17:57 -07:00
|
|
|
|
2014-11-11 08:20:08 -08:00
|
|
|
$table = id(new PhabricatorAuthSSHKeyTableView())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setKeys($keys)
|
|
|
|
->setCanEdit(true)
|
2015-05-22 17:27:56 +10:00
|
|
|
->setNoDataString(pht("You haven't added any SSH Public Keys."));
|
2011-07-22 10:17:57 -07:00
|
|
|
|
2014-01-07 16:16:30 -08:00
|
|
|
$panel = new PHUIObjectBoxView();
|
|
|
|
$header = new PHUIHeaderView();
|
|
|
|
|
2016-05-19 06:03:06 -07:00
|
|
|
$ssh_actions = PhabricatorAuthSSHKeyTableView::newKeyActionsMenu(
|
|
|
|
$viewer,
|
|
|
|
$user);
|
2014-01-07 16:16:30 -08:00
|
|
|
|
2017-09-05 19:30:52 -07:00
|
|
|
return $this->newBox(pht('SSH Public Keys'), $table, array($ssh_actions));
|
2011-07-22 10:17:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|