* 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>
* src/ejabberd_listener.erl: Enable keepalive option

View File

@ -46,6 +46,7 @@
access,
shaper,
tls = false,
tls_required = false,
tls_enabled = false,
tls_options = [],
authentificated = false,
@ -82,6 +83,8 @@
xml:element_to_string(?SERR_INVALID_NAMESPACE)).
-define(INVALID_XML_ERR,
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
@ -117,8 +120,9 @@ init([{SockMod, Socket}, Opts]) ->
_ -> none
end,
StartTLS = lists:member(starttls, Opts),
StartTLSRequired = lists:member(starttls_required, Opts),
TLSEnabled = lists:member(tls, Opts),
TLS = StartTLS orelse TLSEnabled,
TLS = StartTLS orelse StartTLSRequired orelse TLSEnabled,
TLSOpts = lists:filter(fun({certfile, _}) -> true;
(_) -> false
end, Opts),
@ -132,15 +136,16 @@ init([{SockMod, Socket}, Opts]) ->
RecPid = ejabberd_receiver:start(Socket, SockMod, none),
{SockMod, Socket, RecPid}
end,
{ok, wait_for_stream, #state{socket = Socket1,
sockmod = SockMod1,
receiver = ReceiverPid,
tls = TLS,
tls_enabled = TLSEnabled,
tls_options = TLSOpts,
streamid = new_id(),
access = Access,
shaper = Shaper}}.
{ok, wait_for_stream, #state{socket = Socket1,
sockmod = SockMod1,
receiver = ReceiverPid,
tls = TLS,
tls_required = StartTLSRequired,
tls_enabled = TLSEnabled,
tls_options = TLSOpts,
streamid = new_id(),
access = Access,
shaper = Shaper}}.
%%----------------------------------------------------------------------
@ -179,14 +184,23 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
end, cyrsasl:listmech()),
TLS = StateData#state.tls,
TLSEnabled = StateData#state.tls_enabled,
TLSRequired = StateData#state.tls_required,
SockMod = StateData#state.sockmod,
TLSFeature =
case (TLS == true) andalso
(TLSEnabled == false) andalso
(SockMod == gen_tcp) of
true ->
[{xmlelement, "starttls",
[{"xmlns", ?NS_TLS}], []}];
case TLSRequired of
true ->
[{xmlelement, "starttls",
[{"xmlns", ?NS_TLS}],
[{xmlelement, "required",
[], []}]}];
_ ->
[{xmlelement, "starttls",
[{"xmlns", ?NS_TLS}], []}]
end;
false ->
[]
end,
@ -379,9 +393,10 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
{xmlelement, Name, Attrs, Els} = El,
TLS = StateData#state.tls,
TLSEnabled = StateData#state.tls_enabled,
TLSRequired = StateData#state.tls_required,
SockMod = StateData#state.sockmod,
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),
ClientIn = jlib:decode_base64(xml:get_cdata(Els)),
case cyrsasl:server_start(StateData#state.sasl_state,
@ -429,18 +444,28 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
tls_enabled = true
}};
_ ->
case jlib:iq_query_info(El) of
#iq{xmlns = ?NS_REGISTER} = IQ ->
ResIQ = mod_register:process_iq(
{"", "", ""}, {"", ?MYNAME, ""}, IQ),
Res1 = jlib:replace_from_to({"", ?MYNAME, ""},
{"", "", ""},
jlib:iq_to_xml(ResIQ)),
Res = jlib:remove_attr("to", Res1),
send_element(StateData, Res),
{next_state, wait_for_feature_request, StateData};
_ ->
{next_state, wait_for_feature_request, StateData}
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
#iq{xmlns = ?NS_REGISTER} = IQ ->
ResIQ = mod_register:process_iq(
{"", "", ""}, {"", ?MYNAME, ""}, IQ),
Res1 = jlib:replace_from_to({"", ?MYNAME, ""},
{"", "", ""},
jlib:iq_to_xml(ResIQ)),
Res = jlib:remove_attr("to", Res1),
send_element(StateData, Res),
{next_state, wait_for_feature_request, StateData};
_ ->
{next_state, wait_for_feature_request, StateData}
end
end
end;

View File

@ -107,6 +107,7 @@ int ei_x_encode_string_fixed(ei_x_buff* x, const char* s)
#define XML_ERROR 3
#define PARSE_COMMAND 0
#define PARSE_FINAL_COMMAND 1
ei_x_buff event_buf;
@ -208,8 +209,9 @@ static int expat_erl_control(ErlDrvData drv_data,
switch (command)
{
case PARSE_COMMAND:
case PARSE_FINAL_COMMAND:
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)
{

View File

@ -214,6 +214,63 @@
%-define(SERR_,
% ?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,
luser, lserver, lresource}).

View File

@ -1023,7 +1023,6 @@ count_stanza_shift(Nick, Els, StateData) ->
_ ->
count_maxchars_shift(Nick, MaxChars, HL)
end,
lists:max([Shift0, Shift1, Shift2, Shift3]).
count_seconds_shift(Seconds, HistoryList) ->
@ -1087,7 +1086,7 @@ extract_history([{xmlelement, _Name, Attrs, _SubEls} = El | Els], Type) ->
end;
_ ->
case catch list_to_integer(AttrVal) of
IntVal when is_integer(IntVal) and IntVal >= 0 ->
IntVal when is_integer(IntVal) and (IntVal >= 0) ->
IntVal;
_ ->
false
@ -1486,7 +1485,7 @@ process_admin_items_set(UJID, Items, Lang, StateData) ->
JID, outcast,
set_role(JID, none, SD));
{JID, affiliation, A, Reason} when
(A == admin) or (A == owner)->
(A == admin) or (A == owner) ->
SD1 = set_affiliation(JID, A, SD),
SD2 = set_role(JID, moderator, SD1),
send_update_presence(JID, SD2),

View File

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

View File

@ -15,7 +15,8 @@
send_text/2,
new/1,
parse/2,
close/1]).
close/1,
parse_element/1]).
-define(XML_START, 0).
-define(XML_END, 1).
@ -23,6 +24,7 @@
-define(XML_ERROR, 3).
-define(PARSE_COMMAND, 0).
-define(PARSE_FINAL_COMMAND, 1).
-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}) ->
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.