Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 515674
Collapse All | Expand All

(-)file_not_specified_in_diff (-26 / +35 lines)
Line  Link Here
The server gave an authentication error, if optional parameters
The server gave an authentication error, if optional parameters
1
were present in the GS2 Header. Specifically, the "a=" parameter,
1
were present in the GS2 Header. Specifically, the "a=" parameter,
2
that can be used by admins to login as a different user.
2
that can be used by admins to login as a different user.
3
.
3
.
4
This patch is a backport of changes introduced by the commit
4
This patch is a backport of changes introduced by the commit
5
9e9b0eae802ee0508db6780426954efd048e7976 in the upstream Git repository
5
9e9b0eae802ee0508db6780426954efd048e7976 in the upstream Git repository
6
to the ejabberd code base as of version 2.1.10.
6
to the ejabberd code base as of version 2.1.10.
7
--
7
++ b/src/cyrsasl_scram.erl
8
-- a/src/cyrsasl_scram.erl
Lines 34-39 Link Here
34
34
35
-include("ejabberd.hrl").
35
-include("ejabberd.hrl").
36
36
37
-include("jlib.hrl").
38
37
-behaviour(cyrsasl).
39
-behaviour(cyrsasl).
38
40
39
-record(state, {step, stored_key, server_key, username, get_password, check_password,
41
-record(state, {step, stored_key, server_key, username, get_password, check_password,
Lines 52-59 Link Here
52
    {ok, #state{step = 2, get_password = GetPassword}}.
54
    {ok, #state{step = 2, get_password = GetPassword}}.
53
55
54
mech_step(#state{step = 2} = State, ClientIn) ->
56
mech_step(#state{step = 2} = State, ClientIn) ->
55
	case string:tokens(ClientIn, ",") of
57
	case re:split(ClientIn, ",", [{return, list}]) of
56
	[CBind, UserNameAttribute, ClientNonceAttribute] when (CBind == "y") or (CBind == "n") ->
58
	[_CBind, _AuthorizationIdentity, _UserNameAttribute, _ClientNonceAttribute, ExtensionAttribute | _]
59
	when ExtensionAttribute /= [] ->
60
		{error, <<"protocol-error-extension-not-supported">>};
61
	[CBind, _AuthorizationIdentity, UserNameAttribute, ClientNonceAttribute | _]
62
	when (CBind == "y") or (CBind == "n") ->
57
		case parse_attribute(UserNameAttribute) of
63
		case parse_attribute(UserNameAttribute) of
58
                {error, Reason} ->
64
                {error, Reason} ->
59
			{error, Reason};
65
			{error, Reason};
Lines 100-131 Link Here
100
	case string:tokens(ClientIn, ",") of
106
	case string:tokens(ClientIn, ",") of
101
	[GS2ChannelBindingAttribute, NonceAttribute, ClientProofAttribute] ->
107
	[GS2ChannelBindingAttribute, NonceAttribute, ClientProofAttribute] ->
102
		case parse_attribute(GS2ChannelBindingAttribute) of
108
		case parse_attribute(GS2ChannelBindingAttribute) of
103
		{$c, CVal} when (CVal == "biws") or (CVal == "eSws") ->
109
		{$c, CVal} ->
104
		    %% biws is base64 for n,, => channelbinding not supported
110
			ChannelBindingSupport = string:left(jlib:decode_base64(CVal), 1),
105
		    %% eSws is base64 for y,, => channelbinding supported by client only
111
			if (ChannelBindingSupport == "n")
106
 			Nonce = State#state.client_nonce ++ State#state.server_nonce,
112
			or (ChannelBindingSupport == "y") ->
107
			case parse_attribute(NonceAttribute) of
113
				Nonce = State#state.client_nonce ++ State#state.server_nonce,
108
			{$r, CompareNonce} when CompareNonce == Nonce ->
114
				case parse_attribute(NonceAttribute) of
109
				case parse_attribute(ClientProofAttribute) of
115
				{$r, CompareNonce} when CompareNonce == Nonce ->
110
				{$p, ClientProofB64} ->
116
					case parse_attribute(ClientProofAttribute) of
111
					ClientProof = base64:decode(ClientProofB64),
117
					{$p, ClientProofB64} ->
112
					AuthMessage = State#state.auth_message ++ "," ++ string:substr(ClientIn, 1, string:str(ClientIn, ",p=")-1),
118
						ClientProof = base64:decode(ClientProofB64),
113
					ClientSignature = scram:client_signature(State#state.stored_key, AuthMessage),
119
						AuthMessage = State#state.auth_message ++ "," ++ string:substr(ClientIn, 1, string:str(ClientIn, ",p=")-1),
114
					ClientKey = scram:client_key(ClientProof, ClientSignature),
120
						ClientSignature = scram:client_signature(State#state.stored_key, AuthMessage),
115
					CompareStoredKey = scram:stored_key(ClientKey),
121
						ClientKey = scram:client_key(ClientProof, ClientSignature),
116
					if CompareStoredKey == State#state.stored_key ->
122
						CompareStoredKey = scram:stored_key(ClientKey),
117
						ServerSignature = scram:server_signature(State#state.server_key, AuthMessage),
123
						if CompareStoredKey == State#state.stored_key ->
118
						{ok, [{username, State#state.username}], "v=" ++ base64:encode_to_string(ServerSignature)};
124
							ServerSignature = scram:server_signature(State#state.server_key, AuthMessage),
119
					true ->
125
							{ok, [{username, State#state.username}], "v=" ++ base64:encode_to_string(ServerSignature)};
120
						{error, "bad-auth"}
126
						true ->
127
							{error, "bad-auth"}
128
						end;
129
					_Else ->
130
						{error, "bad-protocol"}
121
					end;
131
					end;
132
				{$r, _} ->
133
					{error, "bad-nonce"};
122
				_Else ->
134
				_Else ->
123
					{error, "bad-protocol"}
135
					{error, "bad-protocol"}
124
				end;
136
				end;
125
			{$r, _} ->
137
			true ->
126
				{error, "bad-nonce"};
138
				{error, "bad-channel-binding"}
127
			_Else ->
128
				{error, "bad-protocol"}
129
			end;
139
			end;
130
		_Else ->
140
		_Else ->
131
	   		{error, "bad-protocol"}
141
	   		{error, "bad-protocol"}

Return to bug 515674