mirror of
https://github.com/nextcloud/passman.git
synced 2025-09-29 08:15:50 +08:00
Passman 2.1.0
Lock vault after 3 wrong attempts (Fixes #197) Fix share button, fix shared_key not added to storedCredential after sharing (Fixes #249) Add password app importer. Fixes #248 Fix version check via proxy. Fixes #237 Fix activity app not filtering. Fixes #246 Add EnPass txt importer. Fixes #159 Fix for disabled share button Require vault key for export. Fixes #199 Indicate that sharing only works with users that have 1 or more vaults. Fixes #242 Reset tags on logout. Fixes #245 Ability to enter OTP secret manually. Fixes #198 Create teampass importer. Fixes #244 Signed-off-by: Passman Bot <info@passman.cc>
This commit is contained in:
parent
1c44875b98
commit
af0d560272
11 changed files with 225 additions and 88 deletions
|
@ -4,7 +4,12 @@ This is the bug tracker for the Passman. Find passman-webextension at https://gi
|
|||
|
||||
|
||||
To make it possible for us to help you please fill out below information carefully.
|
||||
|
||||
If you like to make a feature request, please remove the issue template.
|
||||
If you want to fill in a issue, remove the feature request template.
|
||||
-->
|
||||
## Bug report
|
||||
|
||||
### Steps to reproduce
|
||||
1.
|
||||
2.
|
||||
|
@ -19,17 +24,24 @@ Tell us what happens instead
|
|||
### Configuration
|
||||
**Operating system**:
|
||||
|
||||
|
||||
**Browser**:
|
||||
|
||||
|
||||
**Browser**:
|
||||
|
||||
**Extensions that might cause interference**:
|
||||
|
||||
|
||||
|
||||
**Passman version**:
|
||||
|
||||
|
||||
**Nextcloud version**:
|
||||
|
||||
**Operating system**:
|
||||
|
||||
**Web server:**
|
||||
|
||||
**Database:**
|
||||
|
||||
**PHP version:**
|
||||
|
||||
**cloud server:** Nextcloud or ownCloud
|
||||
|
||||
**cloud version:** (see admin page or version.php)
|
||||
|
||||
|
||||
#### Browser log
|
||||
<details>
|
||||
|
@ -41,4 +53,49 @@ a) The javascript console log
|
|||
b) The network log
|
||||
c) ...
|
||||
```
|
||||
</details>
|
||||
</details>
|
||||
|
||||
|
||||
#### Cloud log
|
||||
<!--
|
||||
The log has the name owncloud.log or nextcloud.log and is found in the data folder
|
||||
-->
|
||||
|
||||
<details>
|
||||
<summary>Cloud log</summary>
|
||||
|
||||
```
|
||||
Insert your cloud log here
|
||||
```
|
||||
</details>
|
||||
|
||||
|
||||
## Feature request
|
||||
|
||||
**User type**: Logged-in or public user
|
||||
|
||||
**User level**: Beginners, intermediate or advanced
|
||||
|
||||
### Description
|
||||
<!--
|
||||
Please try to give as much information as you can about your request
|
||||
-->
|
||||
|
||||
### Benefit / value
|
||||
<!--
|
||||
Please explain how it could benefit users of the app, other apps or 3rd party services
|
||||
-->
|
||||
|
||||
### Risk / caveats
|
||||
<!--
|
||||
Please explain the risks and caveats associated with this request
|
||||
-->
|
||||
|
||||
### Sponsorship
|
||||
<!--
|
||||
This greatly accelerates the delivery of a feature
|
||||
-->
|
||||
|
||||
**Are you a developer willing to implement this feature?**: yes/no
|
||||
|
||||
**Can you sponsor the development of this feature or do you know someone who can?**: yes/no
|
||||
|
|
135
README.md
135
README.md
|
@ -1,4 +1,5 @@
|
|||
#Passman
|
||||
Passman is a full featured password manager.
|
||||
|
||||
[](https://travis-ci.org/nextcloud/passman)
|
||||
[](https://www.codacy.com/app/brantje/passman?utm_source=github.com&utm_medium=referral&utm_content=nextcloud/passman&utm_campaign=Badge_Grade)
|
||||
|
@ -6,43 +7,19 @@
|
|||
[](https://scrutinizer-ci.com/g/nextcloud/passman/?branch=master)
|
||||
|
||||
|
||||
Passman is a full featured password manager.
|
||||
Features:
|
||||
- Vaults
|
||||
- Vault key is never sent to the server
|
||||
- Credentials are stored with 256 bit AES
|
||||
- Ability to add custom fields to credentials
|
||||
- Built-in OTP(One Time Password) generator
|
||||
- Password analyzer
|
||||
- Share passwords internally and via link in a secure manner.
|
||||
- Import from various password managers:
|
||||
- KeePass
|
||||
- LastPass
|
||||
- DashLane
|
||||
- ZOHO
|
||||
- Clipperz.is
|
||||
## Contents
|
||||
* [Screenshots](https://github.com/nextcloud/passman#Screenshots)
|
||||
* [Features](https://github.com/nextcloud/passman#features)
|
||||
* [External apps](https://github.com/nextcloud/passman#external-apps)
|
||||
* [Security](https://github.com/nextcloud/passman#security)
|
||||
* [Password generation](https://github.com/nextcloud/passman#password-generation)
|
||||
* [Storing credentials](https://github.com/nextcloud/passman#storing-credentials)
|
||||
* [API](https://github.com/nextcloud/passman#api)
|
||||
* [Docker](https://github.com/nextcloud/passman#docker)
|
||||
* [Maintainers](https://github.com/nextcloud/passman#main-developers)
|
||||
* [Contributors](https://github.com/nextcloud/passman#contributors)
|
||||
|
||||
|
||||
For a demo of this app visit [https://demo.passman.cc](https://demo.passman.cc)
|
||||
|
||||
## Tested on
|
||||
- NextCloud 10 / 11
|
||||
- ownCloud 9.1+
|
||||
|
||||
## Browser extensions
|
||||
At this moment we don't have any extensions available, sorry!
|
||||
However, if you're interested in helping us (or you want to guide us while building)
|
||||
Check out: https://github.com/nextcloud/passman-chrome-extension
|
||||
|
||||
|
||||
## Supported databases
|
||||
- SQL Lite*
|
||||
- MySQL / MariaDB*
|
||||
|
||||
*Tested on travis
|
||||
|
||||
Untested databases:
|
||||
- pgsql
|
||||
|
||||
|
||||
##Screenshots
|
||||
|
@ -56,15 +33,85 @@ Untested databases:
|
|||
|
||||
For more screenshots: [Click here](http://imgur.com/a/giKVt)
|
||||
|
||||
## Encryption (server side)
|
||||
All passwords are encrypted client side AND server side.
|
||||
This means that if you move to another server you have to backup the following from config.php
|
||||
- `passwordsalt`
|
||||
- `secret`
|
||||
|
||||
## Features:
|
||||
- Vaults
|
||||
- Vault key is never sent to the server
|
||||
- Credentials are stored with 256 bit AES (see [security](https://github.com/nextcloud/passman#security))
|
||||
- Ability to add custom fields to credentials
|
||||
- Built-in OTP(One Time Password) generator
|
||||
- Password analyzer
|
||||
- Share passwords internally and via link in a secure manner.
|
||||
- Import from various password managers:
|
||||
- KeePass
|
||||
- LastPass
|
||||
- DashLane
|
||||
- ZOHO
|
||||
- Clipperz.is
|
||||
- EnPass
|
||||
- [ocPasswords](https://github.com/fcturner/passwords)
|
||||
|
||||
|
||||
For a demo of this app visit [https://demo.passman.cc](https://demo.passman.cc)
|
||||
|
||||
## Tested on
|
||||
- NextCloud 10 / 11
|
||||
- ownCloud 9.1+
|
||||
|
||||
|
||||
## External apps
|
||||
- [Firefox / chrome extension](https://github.com/nextcloud/passman-webextension)
|
||||
- [Android app](https://github.com/nextcloud/passman-android)
|
||||
|
||||
|
||||
## Supported databases
|
||||
- SQL Lite*
|
||||
- MySQL / MariaDB*
|
||||
|
||||
*Tested on travis
|
||||
|
||||
Untested databases:
|
||||
- pgsql
|
||||
|
||||
## Security
|
||||
|
||||
### Password generation
|
||||
Passman features a build in password generator.
|
||||
Not it only generates passwords, but it also measures their strength using [zxcvbn](https://github.com/dropbox/zxcvbn).
|
||||

|
||||
|
||||
Generate passwords as you like
|
||||

|
||||
Passwords are generated using the random functions from `sjcl`.
|
||||
|
||||
|
||||
### Storing credentials
|
||||
All passwords are encrypted client side using [sjcl](https://github.com/bitwiseshiftleft/sjcl) which uses AES-256 bit.
|
||||
Users supply a vault key which is feed into sjcl as encryption key.
|
||||
After the credentials are encrypted they are send to the server, there they will be encrypted again.
|
||||
This time using the following routine:
|
||||
- A key is generated using `passwordsalt` and `secret` from config.php *so back those up*
|
||||
- Then the key is [stretched](http://en.wikipedia.org/wiki/Key_stretching) using [Password-Based Key Derivation Function 2](http://en.wikipedia.org/wiki/PBKDF2) (PBKDF2).
|
||||
- [Encrypt-then-MAC](http://en.wikipedia.org/wiki/Authenticated_encryption#Approaches_to_Authenticated_Encryption) (EtM) is used for ensuring the authenticity of the encrypted data.
|
||||
- Uses openssl with the `aes-256-cbc` ciper.
|
||||
- [Initialization vector](http://en.wikipedia.org/wiki/Initialization_vector) (IV) is hidden
|
||||
- [Double Hash-based Message Authentication Code](http://en.wikipedia.org/wiki/Hash-based_message_authentication_code) (HMAC) is applied for verification of the source data.
|
||||
|
||||
|
||||
### Sharing credentials.
|
||||
Passman allows users to share passwords (this can be turned off by an administrator).
|
||||
|
||||
|
||||
|
||||
## API
|
||||
For developers passman offers an [api](https://github.com/nextcloud/passman/wiki/API).
|
||||
|
||||
## Support Passman
|
||||
If you like passman, support us via [patreon](https://www.patreon.com/user?u=4833592) or [paypal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6YS8F97PETVU2)
|
||||
|
||||
Passman is open source, but we would gladly accept a beer (or pizza!)
|
||||
Please consider donating via
|
||||
- [Paypal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6YS8F97PETVU2)
|
||||
- [Patreon](https://www.patreon.com/user?u=4833592)
|
||||
- Bitcoin: 1H2c5tkGX54n48yEtM4Wm4UrAGTW85jQpe
|
||||
|
||||
## Code reviews
|
||||
If you have any improvements regarding our code.
|
||||
|
@ -77,8 +124,8 @@ Please do the following
|
|||
Or if you're feeling lazy, create an issue, and we'll think about it.
|
||||
|
||||
## Docker
|
||||
To run passman with docker you can use `docker run -p 8080:80 -p 8443:443 brantje/passman`
|
||||
To use your own SSL cert mount them as below
|
||||
To run passman with docker you can use `docker run -p 8080:80 -p 8443:443 brantje/passman`
|
||||
You have to supply your own ssl certs.
|
||||
Example:
|
||||
`docker run -p 8080:80 -p 8443:443 -v /directory/cert.pem:/data/ssl/cert.pem -v /directory/cert.key:/data/ssl/cert.key brantje/passman`
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ $manager->registerNotifier(function() {
|
|||
$manager = \OC::$server->getActivityManager();
|
||||
$manager->registerExtension(function() {
|
||||
return new Activity(
|
||||
\OC::$server->getL10NFactory()
|
||||
\OC::$server->getURLGenerator()
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ For an demo of this app visit [https://demo.passman.cc](https://demo.passman.cc)
|
|||
]]></description>
|
||||
|
||||
<licence>AGPL</licence>
|
||||
<version>2.0.2</version>
|
||||
<version>2.1.0</version>
|
||||
<author homepage="https://github.com/brantje">Sander Brand</author>
|
||||
<author homepage="https://github.com/animalillo">Marcos Zuriaga</author>
|
||||
<namespace>Passman</namespace>
|
||||
|
|
|
@ -69,6 +69,7 @@ class TranslationController extends ApiController {
|
|||
|
||||
// js/app/controllers/import.js
|
||||
'import.file.read' => $this->trans->t('File read successfully!'),
|
||||
'import.steps' => $this->trans->t('Follow the following steps to import your file'),
|
||||
|
||||
'import.no.label' => $this->trans->t('Credential has no label, skipping'),
|
||||
'import.adding' => $this->trans->t('Adding {{credential}}'),
|
||||
|
@ -144,7 +145,7 @@ class TranslationController extends ApiController {
|
|||
|
||||
|
||||
// templates/views/partials/edit_credential/otp.html
|
||||
'upload.qr' => $this->trans->t('Upload your OTP qr code'),
|
||||
'upload.qr' => $this->trans->t('Upload or enter your OTP secret'),
|
||||
'current.qr' => $this->trans->t('Current OTP settings'),
|
||||
'issuer' => $this->trans->t('Issuer'),
|
||||
'secret' => $this->trans->t('Secret'),
|
||||
|
@ -173,6 +174,7 @@ class TranslationController extends ApiController {
|
|||
// templates/views/partials/forms/settings/export.html
|
||||
'export.type' => $this->trans->t('Export type'),
|
||||
'export' => $this->trans->t('Export'),
|
||||
'export.confirm.text' => $this->trans->t('Enter vault password to confirm export.'),
|
||||
|
||||
// templates/views/partials/forms/settings/general_settings.html
|
||||
'rename.vault' => $this->trans->t('Rename vault'),
|
||||
|
@ -226,6 +228,7 @@ class TranslationController extends ApiController {
|
|||
|
||||
// templates/vieuws/partials/forms/share_credential/basics.html
|
||||
'search.u.g' => $this->trans->t('Search users or groups...'),
|
||||
'search.result.missing' => $this->trans->t('Missing users? Only users that have vaults are shown.'),
|
||||
'cyphering' => $this->trans->t('Cyphering'),
|
||||
'uploading' => $this->trans->t('Uploading'),
|
||||
'user' => $this->trans->t('User'),
|
||||
|
@ -325,6 +328,7 @@ class TranslationController extends ApiController {
|
|||
'accept' => $this->trans->t('Accept'),
|
||||
'decline' => $this->trans->t('Decline'),
|
||||
'session.time.left' => $this->trans->t('You have {{session_time}} left before logout.'),
|
||||
'vault.locked' => $this->trans->t('Your vault has been locked for {{time}} because of {{tries}} failed attempts!'),
|
||||
|
||||
// templates/views/vaults.html
|
||||
'last.access' => $this->trans->t('Last accessed'),
|
||||
|
|
4
css/passman.min.css
vendored
4
css/passman.min.css
vendored
File diff suppressed because one or more lines are too long
14
js/passman.min.js
vendored
14
js/passman.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -284,4 +284,4 @@ OC.L10N.register(
|
|||
"Dismiss" : "Odrzuć",
|
||||
"seconds ago" : "sekund temu"
|
||||
},
|
||||
"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);");
|
||||
"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>=14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);");
|
||||
|
|
|
@ -281,5 +281,5 @@
|
|||
"Saving..." : "Zapisywanie...",
|
||||
"Dismiss" : "Odrzuć",
|
||||
"seconds ago" : "sekund temu"
|
||||
},"pluralForm" :"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
|
||||
},"pluralForm" :"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>=14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);"
|
||||
}
|
|
@ -23,7 +23,11 @@
|
|||
|
||||
namespace OCA\Passman;
|
||||
|
||||
use OCP\IURLGenerator;
|
||||
|
||||
class Activity implements \OCP\Activity\IExtension {
|
||||
const FILTER_PASSMAN = 'passman';
|
||||
const APP_NAME = 'passman';
|
||||
const TYPE_ITEM_ACTION = 'passman_item_action';
|
||||
const TYPE_ITEM_EXPIRED = 'passman_item_expired';
|
||||
const TYPE_ITEM_SHARED = 'passman_item_shared';
|
||||
|
@ -49,6 +53,13 @@ class Activity implements \OCP\Activity\IExtension {
|
|||
const SUBJECT_ITEM_RENAMED_SELF = 'item_renamed_self';
|
||||
|
||||
|
||||
protected $URLGenerator;
|
||||
|
||||
public function __construct( IURLGenerator $URLGenerator) {
|
||||
$this->URLGenerator = $URLGenerator;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The extension can return an array of additional notification types.
|
||||
* If no additional types are to be added false is to be returned
|
||||
|
@ -57,7 +68,7 @@ class Activity implements \OCP\Activity\IExtension {
|
|||
* @return array|false
|
||||
*/
|
||||
public function getNotificationTypes($languageCode) {
|
||||
$l = \OC::$server->getL10N('passman', $languageCode);
|
||||
$l = \OC::$server->getL10N(self::APP_NAME, $languageCode);
|
||||
return array(
|
||||
self::TYPE_ITEM_ACTION => $l->t('A Passman item has been created, modified or deleted'),
|
||||
self::TYPE_ITEM_EXPIRED => $l->t('A Passman item has expired'),
|
||||
|
@ -75,7 +86,7 @@ class Activity implements \OCP\Activity\IExtension {
|
|||
* @return array|false
|
||||
*/
|
||||
public function filterNotificationTypes($types, $filter) {
|
||||
return $types;
|
||||
return $filter === self::FILTER_PASSMAN ? [self::TYPE_ITEM_ACTION, self::TYPE_ITEM_EXPIRED, self::TYPE_ITEM_SHARED, self::TYPE_ITEM_RENAMED] : $types;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,8 +127,8 @@ class Activity implements \OCP\Activity\IExtension {
|
|||
* @return string|false
|
||||
*/
|
||||
public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) {
|
||||
$l = \OC::$server->getL10NFactory()->get('passman', $languageCode);
|
||||
if ($app === 'passman') {
|
||||
$l = \OC::$server->getL10NFactory()->get(self::APP_NAME, $languageCode);
|
||||
if ($app === self::APP_NAME) {
|
||||
switch ($text) {
|
||||
case self::SUBJECT_ITEM_CREATED:
|
||||
return $l->t('%1$s has been created by %2$s', $params);
|
||||
|
@ -172,7 +183,7 @@ class Activity implements \OCP\Activity\IExtension {
|
|||
* @return array|false
|
||||
*/
|
||||
public function getSpecialParameterList($app, $text) {
|
||||
if ($app === 'passman') {
|
||||
if ($app === self::APP_NAME) {
|
||||
switch ($text) {
|
||||
case self::SUBJECT_ITEM_CREATED:
|
||||
case self::SUBJECT_ITEM_CREATED_SELF:
|
||||
|
@ -247,14 +258,14 @@ class Activity implements \OCP\Activity\IExtension {
|
|||
* @return array|false
|
||||
*/
|
||||
public function getNavigation() {
|
||||
$l = \OC::$server->getL10N('passman');
|
||||
$l = \OC::$server->getL10N(self::APP_NAME);
|
||||
return array(
|
||||
'top' => array(),
|
||||
'apps' => array(
|
||||
'apps' => array( self::FILTER_PASSMAN =>
|
||||
array(
|
||||
'id' => 'passman',
|
||||
'name' => (string) $l->t('Passwords'),
|
||||
'url' => '',//FIXME: Currenlty we cannot link directly to links, so this needs to be fixed... this->URLGenerator->linkToRoute('activity.Activities.showList', array('filter' => 'passman')),
|
||||
'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::FILTER_PASSMAN]),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -267,7 +278,7 @@ class Activity implements \OCP\Activity\IExtension {
|
|||
* @return boolean
|
||||
*/
|
||||
public function isFilterValid($filterValue) {
|
||||
return $filterValue === 'passman';
|
||||
return $filterValue === self::FILTER_PASSMAN;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -280,9 +291,13 @@ class Activity implements \OCP\Activity\IExtension {
|
|||
* @return array|false
|
||||
*/
|
||||
public function getQueryForFilter($filter) {
|
||||
if ($filter === 'passman') {
|
||||
return array('`app` = ?', array('passman'));
|
||||
if ($filter === self::FILTER_PASSMAN) {
|
||||
return [
|
||||
'(`app` = ?)',
|
||||
[self::APP_NAME],
|
||||
];
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
|
@ -9,17 +9,31 @@ $checkVersion = OC::$server->getConfig()->getAppValue('passman', 'check_version'
|
|||
$AppInstance = new App();
|
||||
$localVersion = $AppInstance->getAppInfo("passman")["version"];
|
||||
if ($checkVersion) {
|
||||
// get latest master version
|
||||
$doc = new DOMDocument();
|
||||
$doc->load('https://raw.githubusercontent.com/nextcloud/passman/master/appinfo/info.xml');
|
||||
$root = $doc->getElementsByTagName("info");
|
||||
// get latest master version
|
||||
$version = false;
|
||||
$githubVersion = $l->t('Unable to get version info');
|
||||
foreach ($root as $element) {
|
||||
$versions = $element->getElementsByTagName("version");
|
||||
$version = $versions->item(0)->nodeValue;
|
||||
|
||||
$url = 'https://raw.githubusercontent.com/nextcloud/passman/master/appinfo/info.xml';
|
||||
try {
|
||||
$client = OC::$server->getHTTPClientService()->newClient();
|
||||
$response = $client->get($url);
|
||||
$xml = $response->getBody();
|
||||
} catch (\Exception $e) {
|
||||
$xml = false;
|
||||
}
|
||||
if ($version) {
|
||||
|
||||
if ($xml) {
|
||||
$loadEntities = libxml_disable_entity_loader(true);
|
||||
$data = @simplexml_load_string($xml);
|
||||
libxml_disable_entity_loader($loadEntities);
|
||||
if ($data !== false) {
|
||||
$version = (string)$data->version;
|
||||
} else {
|
||||
libxml_clear_errors();
|
||||
}
|
||||
}
|
||||
|
||||
if ($version !== false) {
|
||||
$githubVersion = $version;
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +50,7 @@ $ciphers = openssl_get_cipher_methods();
|
|||
} ?>
|
||||
Local version: <?php p($localVersion); ?><br/>
|
||||
<?php
|
||||
if (version_compare($githubVersion, $localVersion) === 1) {
|
||||
if ($checkVersion && version_compare($githubVersion, $localVersion) === 1) {
|
||||
p($l->t('A newer version of passman is available'));
|
||||
}
|
||||
?>
|
||||
|
|
Loading…
Add table
Reference in a new issue