Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Pleroma
pleroma
Commits
39f3683a
Commit
39f3683a
authored
Jan 14, 2021
by
lain
Browse files
Pbkdf2: Use it everywhere.
parent
87a31c5c
Pipeline
#34086
failed with stages
in 5 minutes and 46 seconds
Changes
21
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
benchmarks/load_testing/users.ex
View file @
39f3683a
...
...
@@ -55,7 +55,7 @@ defp generate_user(i) do
name:
"Test テスト User
#{
i
}
"
,
email:
"user
#{
i
}
@example.com"
,
nickname:
"nick
#{
i
}
"
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
"test"
),
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
"test"
),
bio:
"Tester Number
#{
i
}
"
,
local:
!remote
}
...
...
lib/pleroma/mfa.ex
View file @
39f3683a
...
...
@@ -71,7 +71,7 @@ def invalidate_backup_code(%User{} = user, hash_code) do
@spec
generate_backup_codes
(
User
.
t
())
::
{
:ok
,
list
(
binary
)}
|
{
:error
,
String
.
t
()}
def
generate_backup_codes
(%
User
{}
=
user
)
do
with
codes
<-
BackupCodes
.
generate
(),
hashed_codes
<-
Enum
.
map
(
codes
,
&
Pleroma
.
Password
.
hash_pwd_salt
/
1
),
hashed_codes
<-
Enum
.
map
(
codes
,
&
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
/
1
),
changeset
<-
Changeset
.
cast_backup_codes
(
user
,
hashed_codes
),
{
:ok
,
_
}
<-
User
.
update_and_set_cache
(
changeset
)
do
{
:ok
,
codes
}
...
...
lib/pleroma/password.ex
deleted
100644 → 0
View file @
87a31c5c
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule
Pleroma
.
Password
do
@moduledoc
"""
This module implements Pleroma.Password passwords in terms of Plug.Crypto.
"""
alias
Plug
.
Crypto
.
KeyGenerator
def
decode64
(
str
)
do
str
|>
String
.
replace
(
"."
,
"+"
)
|>
Base
.
decode64!
(
padding:
false
)
end
def
encode64
(
bin
)
do
bin
|>
Base
.
encode64
(
padding:
false
)
|>
String
.
replace
(
"+"
,
"."
)
end
def
verify_pass
(
password
,
hash
)
do
[
"pbkdf2-"
<>
digest
,
iterations
,
salt
,
hash
]
=
String
.
split
(
hash
,
"$"
,
trim:
true
)
salt
=
decode64
(
salt
)
iterations
=
String
.
to_integer
(
iterations
)
digest
=
String
.
to_atom
(
digest
)
binary_hash
=
KeyGenerator
.
generate
(
password
,
salt
,
digest:
digest
,
iterations:
iterations
,
length:
64
)
encode64
(
binary_hash
)
==
hash
end
def
hash_pwd_salt
(
password
,
opts
\\
[])
do
salt
=
Keyword
.
get_lazy
(
opts
,
:salt
,
fn
->
:crypto
.
strong_rand_bytes
(
16
)
end
)
digest
=
Keyword
.
get
(
opts
,
:digest
,
:sha512
)
iterations
=
Keyword
.
get
(
opts
,
:iterations
,
Pleroma
.
Config
.
get
([
:password
,
:iterations
],
160_000
))
binary_hash
=
KeyGenerator
.
generate
(
password
,
salt
,
digest:
digest
,
iterations:
iterations
,
length:
64
)
"$pbkdf2-
#{
digest
}
$
#{
iterations
}
$
#{
encode64
(
salt
)
}
$
#{
encode64
(
binary_hash
)
}
"
end
end
lib/pleroma/password/pbkdf2.ex
View file @
39f3683a
...
...
@@ -4,7 +4,7 @@
defmodule
Pleroma
.
Password
.
Pbkdf2
do
@moduledoc
"""
This module implements
Pleroma.Password.
Pbkdf2 passwords in terms of Plug.Crypto.
This module implements Pbkdf2 passwords in terms of Plug.Crypto.
"""
alias
Plug
.
Crypto
.
KeyGenerator
...
...
lib/pleroma/user.ex
View file @
39f3683a
...
...
@@ -2187,7 +2187,7 @@ def get_ap_ids_by_nicknames(nicknames) do
defp
put_password_hash
(
%
Ecto
.
Changeset
{
valid?:
true
,
changes:
%{
password:
password
}}
=
changeset
)
do
change
(
changeset
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
password
))
change
(
changeset
,
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
password
))
end
defp
put_password_hash
(
changeset
),
do
:
changeset
...
...
lib/pleroma/web/plugs/authentication_plug.ex
View file @
39f3683a
...
...
@@ -48,7 +48,7 @@ def checkpw(password, "$2" <> _ = password_hash) do
end
def
checkpw
(
password
,
"$pbkdf2"
<>
_
=
password_hash
)
do
Pleroma
.
Password
.
verify_pass
(
password
,
password_hash
)
Pleroma
.
Password
.
Pbkdf2
.
verify_pass
(
password
,
password_hash
)
end
def
checkpw
(
_password
,
_password_hash
)
do
...
...
test/pleroma/mfa_test.exs
View file @
39f3683a
...
...
@@ -30,8 +30,8 @@ test "returns backup codes" do
{
:ok
,
[
code1
,
code2
]}
=
MFA
.
generate_backup_codes
(
user
)
updated_user
=
refresh_record
(
user
)
[
hash1
,
hash2
]
=
updated_user
.
multi_factor_authentication_settings
.
backup_codes
assert
Pleroma
.
Password
.
verify_pass
(
code1
,
hash1
)
assert
Pleroma
.
Password
.
verify_pass
(
code2
,
hash2
)
assert
Pleroma
.
Password
.
Pbkdf2
.
verify_pass
(
code1
,
hash1
)
assert
Pleroma
.
Password
.
Pbkdf2
.
verify_pass
(
code2
,
hash2
)
end
end
...
...
test/pleroma/password/pbkdf2_test.exs
View file @
39f3683a
...
...
@@ -5,10 +5,10 @@
defmodule
Pleroma
.
Password
.
Pbkdf2Test
do
use
Pleroma
.
DataCase
,
async:
true
alias
Pleroma
.
Password
.
Pbkdf2
alias
Pleroma
.
Password
.
Pbkdf2
,
as:
Password
test
"it generates the same hash as pbkd2_elixir"
do
# hash =
Pleroma.Password.
Pbkdf2.hash_pwd_salt("password")
# hash = Pbkdf2.hash_pwd_salt("password")
hash
=
"$pbkdf2-sha512$1$QJpEYw8iBKcnY.4Rm0eCVw$UBPeWQ91RxSv3snxsb/ZzMeG/2aa03c541bbo8vQudREGNta5t8jBQrd00fyJp8RjaqfvgdZxy2rhSwljyu21g"
...
...
@@ -19,14 +19,14 @@ test "it generates the same hash as pbkd2_elixir" do
end
@tag
skip:
"Works when Pbkd2 is present. Source: trust me bro"
test
"
Pleroma.Password.
Pbkdf2 can verify passwords generated with it"
do
hash
=
Password
.
hash_pwd_salt
(
"password"
)
assert
Pleroma
.
Password
.
Pbkdf2
.
verify_pass
(
"password"
,
hash
)
test
"Pbkdf2 can verify passwords generated with it"
do
# Commented to prevent warnings.
# hash = Password.hash_pwd_salt("password")
#
assert Pbkdf2.verify_pass("password", hash)
end
test
"it verifies pbkdf2_elixir hashes"
do
# hash =
Pleroma.Password.
Pbkdf2.hash_pwd_salt("password")
# hash = Pbkdf2.hash_pwd_salt("password")
hash
=
"$pbkdf2-sha512$1$QJpEYw8iBKcnY.4Rm0eCVw$UBPeWQ91RxSv3snxsb/ZzMeG/2aa03c541bbo8vQudREGNta5t8jBQrd00fyJp8RjaqfvgdZxy2rhSwljyu21g"
...
...
test/pleroma/password_test.exs
deleted
100644 → 0
View file @
87a31c5c
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule
Pleroma
.
PasswordTest
do
use
Pleroma
.
DataCase
,
async:
true
alias
Pleroma
.
Password
test
"it generates the same hash as pbkd2_elixir"
do
# hash = Pleroma.Password.hash_pwd_salt("password")
hash
=
"$pbkdf2-sha512$1$QJpEYw8iBKcnY.4Rm0eCVw$UBPeWQ91RxSv3snxsb/ZzMeG/2aa03c541bbo8vQudREGNta5t8jBQrd00fyJp8RjaqfvgdZxy2rhSwljyu21g"
# Use the same randomly generated salt
salt
=
Password
.
decode64
(
"QJpEYw8iBKcnY.4Rm0eCVw"
)
assert
hash
==
Password
.
hash_pwd_salt
(
"password"
,
salt:
salt
)
end
@tag
skip:
"Works when Pbkd2 is present. Source: trust me bro"
test
"Pleroma.Password can verify passwords generated with it"
do
hash
=
Password
.
hash_pwd_salt
(
"password"
)
assert
Pleroma
.
Password
.
verify_pass
(
"password"
,
hash
)
end
test
"it verifies pbkdf2_elixir hashes"
do
# hash = Pleroma.Password.hash_pwd_salt("password")
hash
=
"$pbkdf2-sha512$1$QJpEYw8iBKcnY.4Rm0eCVw$UBPeWQ91RxSv3snxsb/ZzMeG/2aa03c541bbo8vQudREGNta5t8jBQrd00fyJp8RjaqfvgdZxy2rhSwljyu21g"
assert
Password
.
verify_pass
(
"password"
,
hash
)
end
end
test/pleroma/web/auth/basic_auth_test.exs
View file @
39f3683a
...
...
@@ -11,7 +11,7 @@ test "with HTTP Basic Auth used, grants access to OAuth scope-restricted endpoin
conn:
conn
}
do
user
=
insert
(
:user
)
assert
Pleroma
.
Password
.
verify_pass
(
"test"
,
user
.
password_hash
)
assert
Pleroma
.
Password
.
Pbkdf2
.
verify_pass
(
"test"
,
user
.
password_hash
)
basic_auth_contents
=
(
URI
.
encode_www_form
(
user
.
nickname
)
<>
":"
<>
URI
.
encode_www_form
(
"test"
))
...
...
test/pleroma/web/auth/pleroma_authenticator_test.exs
View file @
39f3683a
...
...
@@ -11,7 +11,7 @@ defmodule Pleroma.Web.Auth.PleromaAuthenticatorTest do
setup
do
password
=
"testpassword"
name
=
"AgentSmith"
user
=
insert
(
:user
,
nickname:
name
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
password
))
user
=
insert
(
:user
,
nickname:
name
,
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
password
))
{
:ok
,
[
user:
user
,
name:
name
,
password:
password
]}
end
...
...
test/pleroma/web/auth/totp_authenticator_test.exs
View file @
39f3683a
...
...
@@ -34,7 +34,7 @@ test "checks backup codes" do
hashed_codes
=
backup_codes
|>
Enum
.
map
(
&
Pleroma
.
Password
.
hash_pwd_salt
(
&1
))
|>
Enum
.
map
(
&
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
&1
))
user
=
insert
(
:user
,
...
...
test/pleroma/web/mongoose_im_controller_test.exs
View file @
39f3683a
...
...
@@ -41,13 +41,13 @@ test "/user_exists", %{conn: conn} do
end
test
"/check_password"
,
%{
conn:
conn
}
do
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
"cool"
))
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
"cool"
))
_deactivated_user
=
insert
(
:user
,
nickname:
"konata"
,
deactivated:
true
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
"cool"
)
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
"cool"
)
)
res
=
...
...
test/pleroma/web/o_auth/ldap_authorization_test.exs
View file @
39f3683a
...
...
@@ -18,7 +18,7 @@ defmodule Pleroma.Web.OAuth.LDAPAuthorizationTest do
@tag
@skip
test
"authorizes the existing user using LDAP credentials"
do
password
=
"testpassword"
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
password
))
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
password
))
app
=
insert
(
:oauth_app
,
scopes:
[
"read"
,
"write"
])
host
=
Pleroma
.
Config
.
get
([
:ldap
,
:host
])
|>
to_charlist
...
...
@@ -101,7 +101,7 @@ test "creates a new user after successful LDAP authorization" do
@tag
@skip
test
"disallow authorization for wrong LDAP credentials"
do
password
=
"testpassword"
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
password
))
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
password
))
app
=
insert
(
:oauth_app
,
scopes:
[
"read"
,
"write"
])
host
=
Pleroma
.
Config
.
get
([
:ldap
,
:host
])
|>
to_charlist
...
...
test/pleroma/web/o_auth/mfa_controller_test.exs
View file @
39f3683a
...
...
@@ -20,7 +20,7 @@ defmodule Pleroma.Web.OAuth.MFAControllerTest do
insert
(
:user
,
multi_factor_authentication_settings:
%
MFA
.
Settings
{
enabled:
true
,
backup_codes:
[
Pleroma
.
Password
.
hash_pwd_salt
(
"test-code"
)],
backup_codes:
[
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
"test-code"
)],
totp:
%
MFA
.
Settings
.
TOTP
{
secret:
otp_secret
,
confirmed:
true
}
}
)
...
...
@@ -246,7 +246,7 @@ test "returns access token with valid code", %{conn: conn, app: app} do
hashed_codes
=
backup_codes
|>
Enum
.
map
(
&
Pleroma
.
Password
.
hash_pwd_salt
(
&1
))
|>
Enum
.
map
(
&
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
&1
))
user
=
insert
(
:user
,
...
...
test/pleroma/web/o_auth/o_auth_controller_test.exs
View file @
39f3683a
...
...
@@ -316,7 +316,7 @@ test "with valid params, POST /oauth/register?op=connect redirects to `redirect_
app:
app
,
conn:
conn
}
do
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
"testpassword"
))
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
"testpassword"
))
registration
=
insert
(
:registration
,
user:
nil
)
redirect_uri
=
OAuthController
.
default_redirect_uri
(
app
)
...
...
@@ -347,7 +347,7 @@ test "with unlisted `redirect_uri`, POST /oauth/register?op=connect results in H
app:
app
,
conn:
conn
}
do
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
"testpassword"
))
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
"testpassword"
))
registration
=
insert
(
:registration
,
user:
nil
)
unlisted_redirect_uri
=
"http://cross-site-request.com"
...
...
@@ -790,7 +790,7 @@ test "issues a token for an all-body request" do
test
"issues a token for `password` grant_type with valid credentials, with full permissions by default"
do
password
=
"testpassword"
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
password
))
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
password
))
app
=
insert
(
:oauth_app
,
scopes:
[
"read"
,
"write"
])
...
...
@@ -818,7 +818,7 @@ test "issues a mfa token for `password` grant_type, when MFA enabled" do
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
password
),
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
password
),
multi_factor_authentication_settings:
%
MFA
.
Settings
{
enabled:
true
,
totp:
%
MFA
.
Settings
.
TOTP
{
secret:
otp_secret
,
confirmed:
true
}
...
...
@@ -927,7 +927,7 @@ test "rejects token exchange for valid credentials belonging to unconfirmed user
password
=
"testpassword"
{
:ok
,
user
}
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
password
))
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
password
))
|>
User
.
confirmation_changeset
(
need_confirmation:
true
)
|>
User
.
update_and_set_cache
()
...
...
@@ -955,7 +955,7 @@ test "rejects token exchange for valid credentials belonging to deactivated user
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
password
),
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
password
),
deactivated:
true
)
...
...
@@ -983,7 +983,7 @@ test "rejects token exchange for user with password_reset_pending set to true" d
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
password
),
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
password
),
password_reset_pending:
true
)
...
...
@@ -1012,7 +1012,7 @@ test "rejects token exchange for user with confirmation_pending set to true" do
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
password
),
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
password
),
confirmation_pending:
true
)
...
...
@@ -1040,7 +1040,7 @@ test "rejects token exchange for valid credentials belonging to an unapproved us
user
=
insert
(
:user
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
password
),
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
password
),
approval_pending:
true
)
...
...
test/pleroma/web/plugs/authentication_plug_test.exs
View file @
39f3683a
...
...
@@ -17,7 +17,7 @@ defmodule Pleroma.Web.Plugs.AuthenticationPlugTest do
user
=
%
User
{
id:
1
,
name:
"dude"
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
"guy"
)
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
"guy"
)
}
conn
=
...
...
test/pleroma/web/twitter_api/password_controller_test.exs
View file @
39f3683a
...
...
@@ -92,7 +92,7 @@ test "it returns HTTP 200", %{conn: conn} do
assert
response
=~
"<h2>Password changed!</h2>"
user
=
refresh_record
(
user
)
assert
Pleroma
.
Password
.
verify_pass
(
"test"
,
user
.
password_hash
)
assert
Pleroma
.
Password
.
Pbkdf2
.
verify_pass
(
"test"
,
user
.
password_hash
)
assert
Enum
.
empty?
(
Token
.
get_user_tokens
(
user
))
end
...
...
test/pleroma/web/twitter_api/util_controller_test.exs
View file @
39f3683a
...
...
@@ -397,7 +397,7 @@ test "with proper permissions, valid password and matching new password and conf
assert
json_response
(
conn
,
200
)
==
%{
"status"
=>
"success"
}
fetched_user
=
User
.
get_cached_by_id
(
user
.
id
)
assert
Pleroma
.
Password
.
verify_pass
(
"newpass"
,
fetched_user
.
password_hash
)
==
true
assert
Pleroma
.
Password
.
Pbkdf2
.
verify_pass
(
"newpass"
,
fetched_user
.
password_hash
)
==
true
end
end
...
...
test/support/builders/user_builder.ex
View file @
39f3683a
...
...
@@ -7,7 +7,7 @@ def build(data \\ %{}) do
email:
"test@example.org"
,
name:
"Test Name"
,
nickname:
"testname"
,
password_hash:
Pleroma
.
Password
.
hash_pwd_salt
(
"test"
),
password_hash:
Pleroma
.
Password
.
Pbkdf2
.
hash_pwd_salt
(
"test"
),
bio:
"A tester."
,
ap_id:
"some id"
,
last_digest_emailed_at:
NaiveDateTime
.
truncate
(
NaiveDateTime
.
utc_now
(),
:second
),
...
...
Prev
1
2
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment