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:
Passman Bot 2017-02-17 21:30:22 +01:00
parent 1c44875b98
commit af0d560272
No known key found for this signature in database
GPG key ID: 0E19D13D1D7FAA09
11 changed files with 225 additions and 88 deletions

View file

@ -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
View file

@ -1,4 +1,5 @@
#Passman
Passman is a full featured password manager.
[![Build Status](https://travis-ci.org/nextcloud/passman.svg?branch=master)](https://travis-ci.org/nextcloud/passman)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/749bb288c9fd4592a73056549d44a85e)](https://www.codacy.com/app/brantje/passman?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=nextcloud/passman&amp;utm_campaign=Badge_Grade)
@ -6,43 +7,19 @@
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/nextcloud/passman/badges/quality-score.png?b=master)](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).
![](http://i.imgur.com/2qVBUfM.png)
Generate passwords as you like
![](http://i.imgur.com/jcRicOV.png)
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`

View file

@ -40,7 +40,7 @@ $manager->registerNotifier(function() {
$manager = \OC::$server->getActivityManager();
$manager->registerExtension(function() {
return new Activity(
\OC::$server->getL10NFactory()
\OC::$server->getURLGenerator()
);
});

View file

@ -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>

View file

@ -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

File diff suppressed because one or more lines are too long

14
js/passman.min.js vendored

File diff suppressed because one or more lines are too long

View file

@ -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);");

View file

@ -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);"
}

View file

@ -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;
}
}

View file

@ -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'));
}
?>