25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-28 16:34:13 +01:00

* src/web/ejabberd_web_admin.erl: Changed type of password field

to "password"

* src/jlib.hrl: More stream error defines (thanks to Sergei
Golovan)

* src/ejabberd_c2s.erl: Support for starttls_required option
(thanks to Sergei Golovan)

* src/mod_muc/mod_muc_room.erl: Fixed mistake in case condition
(thanks to Sergei Golovan)

* src/xml_stream.erl: Added function parse_element/1

* src/expat_erl.c: Added PARSE_FINAL_COMMAND

SVN Revision: 289
This commit is contained in:
Alexey Shchepin 2004-12-05 20:54:55 +00:00
parent cc19cb1785
commit da58d568b1
7 changed files with 185 additions and 31 deletions

View File

@ -1,3 +1,21 @@
2004-12-05 Alexey Shchepin <alexey@sevcom.net>
* src/web/ejabberd_web_admin.erl: Changed type of password field
to "password"
* src/jlib.hrl: More stream error defines (thanks to Sergei
Golovan)
* src/ejabberd_c2s.erl: Support for starttls_required option
(thanks to Sergei Golovan)
* src/mod_muc/mod_muc_room.erl: Fixed mistake in case condition
(thanks to Sergei Golovan)
* src/xml_stream.erl: Added function parse_element/1
* src/expat_erl.c: Added PARSE_FINAL_COMMAND
2004-12-03 Alexey Shchepin <alexey@sevcom.net> 2004-12-03 Alexey Shchepin <alexey@sevcom.net>
* src/ejabberd_listener.erl: Enable keepalive option * src/ejabberd_listener.erl: Enable keepalive option

View File

@ -46,6 +46,7 @@
access, access,
shaper, shaper,
tls = false, tls = false,
tls_required = false,
tls_enabled = false, tls_enabled = false,
tls_options = [], tls_options = [],
authentificated = false, authentificated = false,
@ -82,6 +83,8 @@
xml:element_to_string(?SERR_INVALID_NAMESPACE)). xml:element_to_string(?SERR_INVALID_NAMESPACE)).
-define(INVALID_XML_ERR, -define(INVALID_XML_ERR,
xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)). xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
-define(POLICY_VIOLATION_ERR(Lang, Text),
xml:element_to_string(?SERRT_POLICY_VIOLATION(Lang, Text))).
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% API %%% API
@ -117,8 +120,9 @@ init([{SockMod, Socket}, Opts]) ->
_ -> none _ -> none
end, end,
StartTLS = lists:member(starttls, Opts), StartTLS = lists:member(starttls, Opts),
StartTLSRequired = lists:member(starttls_required, Opts),
TLSEnabled = lists:member(tls, Opts), TLSEnabled = lists:member(tls, Opts),
TLS = StartTLS orelse TLSEnabled, TLS = StartTLS orelse StartTLSRequired orelse TLSEnabled,
TLSOpts = lists:filter(fun({certfile, _}) -> true; TLSOpts = lists:filter(fun({certfile, _}) -> true;
(_) -> false (_) -> false
end, Opts), end, Opts),
@ -136,6 +140,7 @@ init([{SockMod, Socket}, Opts]) ->
sockmod = SockMod1, sockmod = SockMod1,
receiver = ReceiverPid, receiver = ReceiverPid,
tls = TLS, tls = TLS,
tls_required = StartTLSRequired,
tls_enabled = TLSEnabled, tls_enabled = TLSEnabled,
tls_options = TLSOpts, tls_options = TLSOpts,
streamid = new_id(), streamid = new_id(),
@ -179,14 +184,23 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
end, cyrsasl:listmech()), end, cyrsasl:listmech()),
TLS = StateData#state.tls, TLS = StateData#state.tls,
TLSEnabled = StateData#state.tls_enabled, TLSEnabled = StateData#state.tls_enabled,
TLSRequired = StateData#state.tls_required,
SockMod = StateData#state.sockmod, SockMod = StateData#state.sockmod,
TLSFeature = TLSFeature =
case (TLS == true) andalso case (TLS == true) andalso
(TLSEnabled == false) andalso (TLSEnabled == false) andalso
(SockMod == gen_tcp) of (SockMod == gen_tcp) of
true ->
case TLSRequired of
true -> true ->
[{xmlelement, "starttls", [{xmlelement, "starttls",
[{"xmlns", ?NS_TLS}], []}]; [{"xmlns", ?NS_TLS}],
[{xmlelement, "required",
[], []}]}];
_ ->
[{xmlelement, "starttls",
[{"xmlns", ?NS_TLS}], []}]
end;
false -> false ->
[] []
end, end,
@ -379,9 +393,10 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
{xmlelement, Name, Attrs, Els} = El, {xmlelement, Name, Attrs, Els} = El,
TLS = StateData#state.tls, TLS = StateData#state.tls,
TLSEnabled = StateData#state.tls_enabled, TLSEnabled = StateData#state.tls_enabled,
TLSRequired = StateData#state.tls_required,
SockMod = StateData#state.sockmod, SockMod = StateData#state.sockmod,
case {xml:get_attr_s("xmlns", Attrs), Name} of case {xml:get_attr_s("xmlns", Attrs), Name} of
{?NS_SASL, "auth"} -> {?NS_SASL, "auth"} when not ((SockMod == gen_tcp) and TLSRequired) ->
Mech = xml:get_attr_s("mechanism", Attrs), Mech = xml:get_attr_s("mechanism", Attrs),
ClientIn = jlib:decode_base64(xml:get_cdata(Els)), ClientIn = jlib:decode_base64(xml:get_cdata(Els)),
case cyrsasl:server_start(StateData#state.sasl_state, case cyrsasl:server_start(StateData#state.sasl_state,
@ -429,6 +444,15 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
tls_enabled = true tls_enabled = true
}}; }};
_ -> _ ->
if
(SockMod == gen_tcp) and TLSRequired ->
Lang = StateData#state.lang,
send_text(StateData, ?POLICY_VIOLATION_ERR(
Lang,
"Use of STARTTLS required") ++
?STREAM_TRAILER),
{stop, normal, StateData};
true ->
case jlib:iq_query_info(El) of case jlib:iq_query_info(El) of
#iq{xmlns = ?NS_REGISTER} = IQ -> #iq{xmlns = ?NS_REGISTER} = IQ ->
ResIQ = mod_register:process_iq( ResIQ = mod_register:process_iq(
@ -442,6 +466,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
_ -> _ ->
{next_state, wait_for_feature_request, StateData} {next_state, wait_for_feature_request, StateData}
end end
end
end; end;
wait_for_feature_request({xmlstreamend, _Name}, StateData) -> wait_for_feature_request({xmlstreamend, _Name}, StateData) ->

View File

@ -107,6 +107,7 @@ int ei_x_encode_string_fixed(ei_x_buff* x, const char* s)
#define XML_ERROR 3 #define XML_ERROR 3
#define PARSE_COMMAND 0 #define PARSE_COMMAND 0
#define PARSE_FINAL_COMMAND 1
ei_x_buff event_buf; ei_x_buff event_buf;
@ -208,8 +209,9 @@ static int expat_erl_control(ErlDrvData drv_data,
switch (command) switch (command)
{ {
case PARSE_COMMAND: case PARSE_COMMAND:
case PARSE_FINAL_COMMAND:
ei_x_new_with_version(&event_buf); ei_x_new_with_version(&event_buf);
res = XML_Parse(d->parser, buf, len, 0); res = XML_Parse(d->parser, buf, len, command == PARSE_FINAL_COMMAND);
if(!res) if(!res)
{ {

View File

@ -214,6 +214,63 @@
%-define(SERR_, %-define(SERR_,
% ?STREAM_ERROR("")). % ?STREAM_ERROR("")).
-define(STREAM_ERRORT(Condition, Lang, Text),
{xmlelement, "stream:error",
[],
[{xmlelement, Condition, [{"xmlns", ?NS_STREAMS}], []},
{xmlelement, "text", [{"xml:lang", Lang}, {"xmlns", ?NS_STREAMS}],
[{xmlcdata, translate:translate(Lang, Text)}]}]}).
-define(SERRT_BAD_FORMAT(Lang, Text),
?STREAM_ERRORT("bad-format", Lang, Text)).
-define(SERRT_BAD_NAMESPACE_PREFIX(Lang, Text),
?STREAM_ERRORT("bad-namespace-prefix", Lang, Text)).
-define(SERRT_CONFLICT(Lang, Text),
?STREAM_ERRORT("conflict", Lang, Text)).
-define(SERRT_CONNECTION_TIMEOUT(Lang, Text),
?STREAM_ERRORT("connection-timeout", Lang, Text)).
-define(SERRT_HOST_GONE(Lang, Text),
?STREAM_ERRORT("host-gone", Lang, Text)).
-define(SERRT_HOST_UNKNOWN(Lang, Text),
?STREAM_ERRORT("host-unknown", Lang, Text)).
-define(SERRT_IMPROPER_ADDRESSING(Lang, Text),
?STREAM_ERRORT("improper-addressing", Lang, Text)).
-define(SERRT_INTERNAL_SERVER_ERROR(Lang, Text),
?STREAM_ERRORT("internal-server-error", Lang, Text)).
-define(SERRT_INVALID_FROM(Lang, Text),
?STREAM_ERRORT("invalid-from", Lang, Text)).
-define(SERRT_INVALID_ID(Lang, Text),
?STREAM_ERRORT("invalid-id", Lang, Text)).
-define(SERRT_INVALID_NAMESPACE(Lang, Text),
?STREAM_ERRORT("invalid-namespace", Lang, Text)).
-define(SERRT_INVALID_XML(Lang, Text),
?STREAM_ERRORT("invalid-xml", Lang, Text)).
-define(SERRT_NOT_AUTHORIZED(Lang, Text),
?STREAM_ERRORT("not-authorized", Lang, Text)).
-define(SERRT_POLICY_VIOLATION(Lang, Text),
?STREAM_ERRORT("policy-violation", Lang, Text)).
-define(SERRT_REMOTE_CONNECTION_FAILED(Lang, Text),
?STREAM_ERRORT("remote-connection-failed", Lang, Text)).
-define(SERRT_RESOURSE_CONSTRAINT(Lang, Text),
?STREAM_ERRORT("resource-constraint", Lang, Text)).
-define(SERRT_RESTRICTED_XML(Lang, Text),
?STREAM_ERRORT("restricted-xml", Lang, Text)).
% TODO: include hostname or IP
-define(SERRT_SEE_OTHER_HOST(Lang, Text),
?STREAM_ERRORT("see-other-host", Lang, Text)).
-define(SERRT_SYSTEM_SHUTDOWN(Lang, Text),
?STREAM_ERRORT("system-shutdown", Lang, Text)).
-define(SERRT_UNSUPPORTED_ENCODING(Lang, Text),
?STREAM_ERRORT("unsupported-encoding", Lang, Text)).
-define(SERRT_UNSUPPORTED_STANZA_TYPE(Lang, Text),
?STREAM_ERRORT("unsupported-stanza-type", Lang, Text)).
-define(SERRT_UNSUPPORTED_VERSION(Lang, Text),
?STREAM_ERRORT("unsupported-version", Lang, Text)).
-define(SERRT_XML_NOT_WELL_FORMED(Lang, Text),
?STREAM_ERRORT("xml-not-well-formed", Lang, Text)).
%-define(SERRT_(Lang, Text),
% ?STREAM_ERRORT("", Lang, Text)).
-record(jid, {user, server, resource, -record(jid, {user, server, resource,
luser, lserver, lresource}). luser, lserver, lresource}).

View File

@ -1023,7 +1023,6 @@ count_stanza_shift(Nick, Els, StateData) ->
_ -> _ ->
count_maxchars_shift(Nick, MaxChars, HL) count_maxchars_shift(Nick, MaxChars, HL)
end, end,
lists:max([Shift0, Shift1, Shift2, Shift3]). lists:max([Shift0, Shift1, Shift2, Shift3]).
count_seconds_shift(Seconds, HistoryList) -> count_seconds_shift(Seconds, HistoryList) ->
@ -1087,7 +1086,7 @@ extract_history([{xmlelement, _Name, Attrs, _SubEls} = El | Els], Type) ->
end; end;
_ -> _ ->
case catch list_to_integer(AttrVal) of case catch list_to_integer(AttrVal) of
IntVal when is_integer(IntVal) and IntVal >= 0 -> IntVal when is_integer(IntVal) and (IntVal >= 0) ->
IntVal; IntVal;
_ -> _ ->
false false

View File

@ -1228,7 +1228,7 @@ user_info(User, Query, Lang) ->
end, lists:sort(Resources)))] end, lists:sort(Resources)))]
end, end,
Password = ejabberd_auth:get_password_s(User), Password = ejabberd_auth:get_password_s(User),
FPassword = [?INPUT("text", "password", Password), ?C(" "), FPassword = [?INPUT("password", "password", Password), ?C(" "),
?INPUTT("submit", "chpassword", "Change Password")], ?INPUTT("submit", "chpassword", "Change Password")],
QueueLen = length(mnesia:dirty_read({offline_msg, User})), QueueLen = length(mnesia:dirty_read({offline_msg, User})),
FQueueLen = [?AC("queue/", FQueueLen = [?AC("queue/",

View File

@ -15,7 +15,8 @@
send_text/2, send_text/2,
new/1, new/1,
parse/2, parse/2,
close/1]). close/1,
parse_element/1]).
-define(XML_START, 0). -define(XML_START, 0).
-define(XML_END, 1). -define(XML_END, 1).
@ -23,6 +24,7 @@
-define(XML_ERROR, 3). -define(XML_ERROR, 3).
-define(PARSE_COMMAND, 0). -define(PARSE_COMMAND, 0).
-define(PARSE_FINAL_COMMAND, 1).
-record(xml_stream_state, {callback_pid, port, stack}). -record(xml_stream_state, {callback_pid, port, stack}).
@ -123,3 +125,54 @@ parse(#xml_stream_state{callback_pid = CallbackPid,
close(#xml_stream_state{port = Port}) -> close(#xml_stream_state{port = Port}) ->
port_close(Port). port_close(Port).
parse_element(Str) ->
Port = open_port({spawn, expat_erl}, [binary]),
Res = port_control(Port, ?PARSE_FINAL_COMMAND, Str),
port_close(Port),
process_element_events(binary_to_term(Res)).
process_element_events(Events) ->
process_element_events(Events, []).
process_element_events([], _Stack) ->
{error, parse_error};
process_element_events([Event | Events], Stack) ->
case Event of
{?XML_START, {Name, Attrs}} ->
process_element_events(
Events, [{xmlelement, Name, Attrs, []} | Stack]);
{?XML_END, _EndName} ->
case Stack of
[{xmlelement, Name, Attrs, Els} | Tail] ->
NewEl = {xmlelement, Name, Attrs, lists:reverse(Els)},
case Tail of
[] ->
if
Events == [] ->
NewEl;
true ->
{error, parse_error}
end;
[{xmlelement, Name1, Attrs1, Els1} | Tail1] ->
process_element_events(
Events,
[{xmlelement, Name1, Attrs1, [NewEl | Els1]} |
Tail1])
end
end;
{?XML_CDATA, CData} ->
case Stack of
[{xmlelement, Name, Attrs, Els} | Tail] ->
process_element_events(
Events,
[{xmlelement, Name, Attrs, [{xmlcdata, CData} | Els]} |
Tail]);
[] ->
process_element_events(Events, [])
end;
{?XML_ERROR, Err} ->
{error, Err}
end.