Does more stuff now.

This commit is contained in:
Craig Everett 2018-06-06 15:44:09 +09:00
parent 8a360fb927
commit 05a457bbc2
3 changed files with 179 additions and 31 deletions

View File

@ -147,6 +147,12 @@ do(["dialyze"]) ->
done(zx_local:dialyze());
do(["create", "user"]) ->
done(zx_local:create_user());
do(["create", "userfile"]) ->
done(zx_local:create_userfile());
do(["export", "user"]) ->
done(zx_local:export_user());
do(["import", "user", ZdufFile]) ->
done(zx_local:import_user(ZdufFile));
do(["create", "keypair"]) ->
done(zx_local:grow_a_pair());
do(["drop", "key", Realm, KeyName]) ->
@ -155,8 +161,8 @@ do(["create", "plt"]) ->
done(zx_local:create_plt());
do(["create", "realm"]) ->
done(zx_local:create_realm());
do(["create", "realmfile", Realm]) ->
done(zx_local:create_realmfile(Realm, "."));
do(["create", "realmfile"]) ->
done(zx_local:create_realmfile());
do(["takeover", Realm]) ->
done(zx_local:takeover(Realm));
do(["abdicate", Realm]) ->

View File

@ -17,7 +17,8 @@
takeover/1, abdicate/1, set_timeout/1, add_mirror/0, drop_mirror/0,
create_plt/0, dialyze/0,
grow_a_pair/0, drop_key/1,
create_user/0, create_realm/0, create_realmfile/2]).
create_user/0, create_userfile/0, export_user/0, import_user/1,
create_realm/0, create_realmfile/0, create_realmfile/1]).
-include("zx_logger.hrl").
@ -785,30 +786,15 @@ dialyze() ->
%% Execute the key generation procedure for 16k RSA keys once and then terminate.
grow_a_pair() ->
ok = file:set_cwd(zx_lib:zomp_dir()),
case zx_lib:list_realms() of
[] ->
{error, "No realms configured.", 61};
[Realm] ->
grow_a_pair(Realm);
Realms ->
Realm = zx_tty:select_string(Realms),
grow_a_pair(Realm)
case select_realm() of
error -> {error, "No realms configured.", 61};
Realm -> grow_a_pair(Realm)
end.
grow_a_pair(Realm) ->
Pattern = zx_lib:path(etc, Realm) ++ "*.user",
case [filename:basename(F, ".user") || F <- filelib:wildcard(Pattern)] of
[] ->
{ok, UserName} = create_user(#user_data{realm = Realm}),
grow_a_pair(UserName);
[UserName] ->
grow_a_pair(Realm, UserName);
UserNames ->
UserName = zx_tty:select_string(UserNames),
grow_a_pair(Realm, UserName)
end.
UserName = select_user(Realm),
grow_a_pair(Realm, UserName).
grow_a_pair(Realm, UserName) ->
@ -901,7 +887,7 @@ store_realm(#realm_init{realm = Realm,
ok = store_user(Sysop),
RealmConfPath = filename:join(zx_lib:path(etc, Realm), "realm.conf"),
ok = zx_lib:write_terms(RealmConfPath, RealmConf),
ok = create_realmfile(Realm, "."),
ok = create_realmfile(Realm),
ZRF = Realm ++ ".zrf",
Message =
"===========================================================================~n"
@ -1119,7 +1105,7 @@ create_user(U = #user_data{realm = Realm,
create_user(U#user_data{contact_info = none});
"" ->
ok = store_user(U),
{ok, UserName};
UserName;
_ ->
ok = io:format("~nArglebargle, glop-glyf!?!~n~n"),
create_user(U)
@ -1145,6 +1131,136 @@ store_user(#user_data{realm = Realm,
log(info, "User ~tp created.", [{Realm, UserName}]).
-spec create_userfile() -> ok.
create_userfile() ->
case select_realm() of
error -> {error, "No realms configured.", 61};
Realm -> create_userfile(Realm)
end.
create_userfile(Realm) ->
UserName = select_user(Realm),
UserConf = filename:join(zx_lib:path(etc, Realm), UserName ++ ".user"),
{ok, UserData} = file:consult(UserConf),
Keys = proplists:get_value(keys, UserData),
Load =
fun(KeyName, Acc) ->
case file:read_file(zx_key:path(public, {Realm, KeyName})) of
{ok, Data} -> [{KeyName, Data} | Acc];
_ -> Acc
end
end,
PubKeyData = lists:foldl(Load, [], Keys),
UserFile = Realm ++ "-" ++ UserName ++ ".zpuf",
Bin = term_to_binary({UserData, PubKeyData}),
ok = file:write_file(UserFile, Bin),
Message =
"Wrote Zomp public user file to ~tp.~n"
"This file can be given to a sysop from ~tp and added to the realm.~n"
"It ONLY contains PUBLIC KEY data.~n",
io:format(Message, [UserFile, Realm]).
-spec export_user() -> ok.
export_user() ->
case select_realm() of
error -> {error, "No realms configured.", 61};
Realm -> export_user(Realm)
end.
export_user(Realm) ->
UserName = select_user(Realm),
UserConf = filename:join(zx_lib:path(etc, Realm), UserName ++ ".user"),
{ok, UserData} = file:consult(UserConf),
Keys = proplists:get_value(keys, UserData),
Load =
fun(KeyName, Acc) ->
Pub =
case file:read_file(zx_key:path(public, {Realm, KeyName})) of
{ok, PD} -> PD;
_ -> none
end,
Key =
case file:read_file(zx_key:path(private, {Realm, KeyName})) of
{ok, KD} -> KD;
_ -> none
end,
[{KeyName, Key, Pub} | Acc]
end,
KeyData = lists:foldl(Load, [], Keys),
UserFile = Realm ++ "-" ++ UserName ++ ".zduf",
Bin = term_to_binary({UserData, KeyData}),
ok = file:write_file(UserFile, Bin),
Message =
"Wrote Zomp DANGEROUS user file to ~tp.~n"
"WARNING: This file contains your PRIVATE KEYS and should NEVER be shared with "
"anyone. Its only use is for the \"import user [.zduf]\" command!~n",
io:format(Message, [UserFile]).
-spec import_user(file:filename()) -> zx:outcome().
import_user(ZDUF) ->
case file:read_file(ZDUF) of
{ok, Bin} -> import_user2(Bin);
{error, enoent} -> {error, "Bad path/missing file.", 2};
{error, eacces} -> {error, "Can't read file: bad permissions.", 13};
{error, eisdir} -> {error, "The path provided is a directory.", 21};
Error -> Error
end.
import_user2(Bin) ->
case zx_lib:b_to_t(Bin) of
{ok, {UserData, []}} ->
ok = log(info, "Note: This user file does not have any keys."),
import_user3(UserData, []);
{ok, {UserData, KeyData}} ->
import_user3(UserData, KeyData);
error ->
{error, "Bad .zduf data. Is this really a legitimate .zduf?", 1}
end.
import_user3(UserData, KeyData) ->
Realm = proplists:get_value(realm, UserData),
UserName = proplists:get_value(username, UserData),
case filelib:is_dir(zx_lib:path(etc, Realm)) of
true ->
UserConf = filename:join(zx_lib:path(etc, Realm), UserName ++ ".user"),
ok = zx_lib:write_terms(UserConf, UserData),
import_user4(Realm, UserName, KeyData);
false ->
{error, "User is from a realm which is not available locally.", 1}
end.
import_user4(Realm, UserName, KeyData) ->
Write =
fun
({KeyName, KeyBin, none}) ->
KeyID = {Realm, KeyName},
file:write_file(zx_key:path(private, KeyID), KeyBin);
({KeyName, none, PubBin}) ->
KeyID = {Realm, KeyName},
file:write_file(zx_key:path(public, KeyID), PubBin);
({KeyName, KeyBin, PubBin}) ->
KeyID = {Realm, KeyName},
file:write_file(zx_key:path(private, KeyID), KeyBin),
file:write_file(zx_key:path(public, KeyID), PubBin);
({KeyName, PubBin}) ->
ok = log(info, "This file is probably a .zpuf, not a .zduf"),
KeyID = {Realm, KeyName},
file:write_file(zx_key:path(public, KeyID), PubBin)
end,
ok = lists:foreach(Write, KeyData),
log(info, "Imported user ~ts to realm ~ts.", [UserName, Realm]).
-spec list_users(Realm) -> UserNames
when Realm :: zx:realm(),
UserNames :: [zx:user_name()].
@ -1288,18 +1404,23 @@ make_realm_dirs(Realm) ->
% io:format("~tp~n", [ZompSettings]).
-spec create_realmfile(Realm, Dir) -> ok
when Realm :: zx:realm(),
Dir :: file:filename().
-spec create_realmfile() -> ok.
create_realmfile(Realm, Dir) ->
create_realmfile() ->
Realm = select_realm(),
create_realmfile(Realm).
-spec create_realmfile(zx:realm()) -> ok.
create_realmfile(Realm) ->
{ok, RealmConf} = zx_lib:load_realm_conf(Realm),
ok = log(info, "Realm found, creating realm file..."),
KeyName = maps:get(key, RealmConf),
PubKeyPath = zx_key:path(public, {Realm, KeyName}),
{ok, PubDER} = file:read_file(PubKeyPath),
Blob = term_to_binary({RealmConf, PubDER}),
ZRF = filename:join(Dir, Realm ++ ".zrf"),
ZRF = Realm ++ ".zrf",
ok = file:write_file(ZRF, Blob),
log(info, "Realm conf file written to ~ts", [ZRF]).
@ -1411,3 +1532,24 @@ drop_mirror(SysConf) ->
Selection = zx_tty:select(Options),
zx_sys_conf:rem_mirror(Selection, SysConf)
end.
-spec select_realm() -> {ok, zx:realm()} | error.
select_realm() ->
case zx_lib:list_realms() of
[] -> error;
[Realm] -> Realm;
Realms -> zx_tty:select_string(Realms)
end.
-spec select_user(zx:realm()) -> zx:user_name().
select_user(Realm) ->
Pattern = filename:join(zx_lib:path(etc, Realm), "*.user"),
case [filename:basename(F, ".user") || F <- filelib:wildcard(Pattern)] of
[] -> create_user(#user_data{realm = Realm});
[UserName] -> UserName;
UserNames -> zx_tty:select_string(UserNames)
end.

View File

@ -136,7 +136,7 @@ timeout(#d{timeout = Timeout}) ->
%% @doc
%% Set the timeout attribute to a new value.
timeout(Value, Data) when is_integer(Value) and Value > 0 ->
timeout(Value, Data) when Value > 0 ->
Data#d{timeout = Value}.