1717-include_lib (" kernel/include/file.hrl" ).
1818-endif .
1919
20- -export ([start_link /2 , start_link /3 , extract_hidden_pass /0 ,
20+ -export ([start_link /3 , start_link /4 , extract_hidden_pass /0 ,
2121 extract_hidden_pass /1 , stop /0 ]).
2222-export ([init /1 , handle_call /3 , handle_cast /2 ,
2323 handle_info /2 , terminate /2 , code_change /3 ]).
@@ -147,17 +147,17 @@ remove_old_integrity_tokens(Name, Paths) ->
147147get_key_id_in_use (Name ) ->
148148 gen_server :call (Name , get_key_id_in_use , infinity ).
149149
150- start_link (Logger , PasswordPromptAllowed ) ->
151- start_link (Logger , PasswordPromptAllowed , gosecrets_cfg_path ()).
150+ start_link (Logger , PasswordPromptAllowed , ReadOnly ) ->
151+ start_link (Logger , PasswordPromptAllowed , ReadOnly , gosecrets_cfg_path ()).
152152
153- start_link (Logger , PasswordPromptAllowed , ConfigPath ) ->
153+ start_link (Logger , PasswordPromptAllowed , ReadOnly , ConfigPath ) ->
154154 gen_server :start_link ({local , ? MODULE }, ? MODULE ,
155- [ConfigPath , Logger , PasswordPromptAllowed ], []).
155+ [ConfigPath , Logger , PasswordPromptAllowed , ReadOnly ], []).
156156
157157stop () ->
158158 gen_server :call (? MODULE , stop , infinity ).
159159
160- prompt_the_password (State , Retries ) ->
160+ prompt_the_password (State , Retries , ReadOnly ) ->
161161 StdIn =
162162 case application :get_env (handle_ctrl_c ) of
163163 {ok , true } ->
@@ -166,7 +166,7 @@ prompt_the_password(State, Retries) ->
166166 undefined
167167 end ,
168168 try
169- prompt_the_password (State , Retries , StdIn )
169+ prompt_the_password (State , Retries , ReadOnly , StdIn )
170170 after
171171 case StdIn of
172172 undefined ->
@@ -176,12 +176,12 @@ prompt_the_password(State, Retries) ->
176176 end
177177 end .
178178
179- prompt_the_password (State , MaxRetries , StdIn ) ->
179+ prompt_the_password (State , MaxRetries , ReadOnly , StdIn ) ->
180180 case open_udp_socket (State ) of
181181 {ok , Socket } ->
182182 try
183183 save_port_file (Socket ),
184- prompt_the_password (State , MaxRetries , StdIn ,
184+ prompt_the_password (State , MaxRetries , ReadOnly , StdIn ,
185185 Socket , _RetriesLeft = MaxRetries )
186186 after
187187 file :delete (port_file_path ()),
@@ -191,7 +191,7 @@ prompt_the_password(State, MaxRetries, StdIn) ->
191191 {error , {udp_socket_open_failed , Error }}
192192 end .
193193
194- prompt_the_password (State , MaxRetries , StdIn , Socket , RetriesLeft ) ->
194+ prompt_the_password (State , MaxRetries , ReadOnly , StdIn , Socket , RetriesLeft ) ->
195195 {ok , {Addr , Port }} = inet :sockname (Socket ),
196196 log (info , " Waiting for the master password to be supplied (UDP: ~p :~b ). "
197197 " Attempt ~p (~p attempts left)" ,
@@ -201,7 +201,7 @@ prompt_the_password(State, MaxRetries, StdIn, Socket, RetriesLeft) ->
201201 log (error , " Password prompt interrupted: ~p " , [M ], State ),
202202 {error , interrupted };
203203 {udp , Socket , FromAddr , FromPort , Password } ->
204- case call_init (? HIDE (Password ), State ) of
204+ case call_init (? HIDE (Password ), ReadOnly , State ) of
205205 ok ->
206206 gen_udp :send (Socket , FromAddr , FromPort , <<" ok" >>),
207207 ok ;
@@ -210,7 +210,7 @@ prompt_the_password(State, MaxRetries, StdIn, Socket, RetriesLeft) ->
210210 State ),
211211 gen_udp :send (Socket , FromAddr , FromPort , <<" retry" >>),
212212 timer :sleep (1000 ),
213- prompt_the_password (State , MaxRetries , StdIn ,
213+ prompt_the_password (State , MaxRetries , ReadOnly , StdIn ,
214214 Socket , RetriesLeft - 1 );
215215 {Reply , _Reason } when Reply == error ;
216216 Reply == wrong_password ->
@@ -219,7 +219,7 @@ prompt_the_password(State, MaxRetries, StdIn, Socket, RetriesLeft) ->
219219 end
220220 end .
221221
222- init ([GosecretsCfgPath , Logger , PasswordPromptAllowed ]) ->
222+ init ([GosecretsCfgPath , Logger , PasswordPromptAllowed , ReadOnly ]) ->
223223 State = # state {config = GosecretsCfgPath ,
224224 logger = Logger },
225225
@@ -235,7 +235,7 @@ init([GosecretsCfgPath, Logger, PasswordPromptAllowed]) ->
235235 HiddenPass = extract_hidden_pass (),
236236
237237 init_gosecrets (HiddenPass , _MaxRetries = 3 , PasswordPromptAllowed ,
238- NewState ),
238+ ReadOnly , NewState ),
239239
240240 {ok , NewState }.
241241
@@ -250,14 +250,15 @@ save_config(CfgPath, Cfg, State) ->
250250 erlang :error ({write_failed , CfgPath , Error })
251251 end .
252252
253- init_gosecrets (HiddenPass , MaxRetries , PasswordPromptAllowed , State ) ->
254- case call_init (HiddenPass , State ) of
253+ init_gosecrets (HiddenPass , MaxRetries , PasswordPromptAllowed , ReadOnly ,
254+ State ) ->
255+ case call_init (HiddenPass , ReadOnly , State ) of
255256 ok -> ok ;
256257 {wrong_password , ErrorMsg } ->
257258 case PasswordPromptAllowed and should_prompt_the_password (State ) of
258259 true ->
259260 try
260- case prompt_the_password (State , MaxRetries ) of
261+ case prompt_the_password (State , MaxRetries , ReadOnly ) of
261262 ok ->
262263 ok ;
263264 {error , Error } ->
@@ -284,8 +285,8 @@ init_gosecrets(HiddenPass, MaxRetries, PasswordPromptAllowed, State) ->
284285 erlang :error ({gosecrets_init_failed , Error })
285286 end .
286287
287- call_init (HiddenPass , State ) ->
288- case call_gosecrets ({init , HiddenPass }, State ) of
288+ call_init (HiddenPass , ReadOnly , State ) ->
289+ case call_gosecrets ({init , ReadOnly , HiddenPass }, State ) of
289290 ok ->
290291 memorize_hidden_pass (HiddenPass ),
291292 log (info , " Init complete. Password (if used) accepted." , [], State ),
@@ -465,7 +466,7 @@ gosecret_do_process_exit(Port, {'EXIT', Port, Reason}) ->
465466gosecret_do_process_exit (_Port , {'EXIT' , _ , Reason }) ->
466467 exit (Reason ).
467468
468- encode ({init , HiddenPass }) ->
469+ encode ({init_read_only , HiddenPass }) ->
469470 BinaryPassword = encode_password (HiddenPass ),
470471 <<1 , BinaryPassword /binary >>;
471472encode (get_keys_ref ) ->
@@ -518,7 +519,15 @@ encode({remove_old_integrity_tokens, Paths}) ->
518519 PathsBin = list_to_binary ([encode_param (P ) || P <- Paths ]),
519520 <<18 , PathsBin /binary >>;
520521encode (get_key_id_in_use ) ->
521- <<19 >>.
522+ <<19 >>;
523+ encode ({init , IsReadOnly , HiddenPass }) ->
524+ BinaryPassword = encode_password (HiddenPass ),
525+ ReadOnlyBin = case IsReadOnly of
526+ true -> <<1 >>;
527+ false -> <<0 >>
528+ end ,
529+ <<20 , (encode_param (ReadOnlyBin ))/binary ,
530+ (encode_param (BinaryPassword ))/binary >>.
522531
523532encode_param (B ) when is_atom (B ) ->
524533 encode_param (atom_to_binary (B ));
@@ -1157,7 +1166,7 @@ upgrade_from_7_2_no_password_test() ->
11571166 undefined ,
11581167 fun (CfgPath ) ->
11591168 ok = file :write_file (DKeyPath , base64 :decode (DKeyNoPass )),
1160- {ok , Pid } = start_link (default , true , CfgPath ),
1169+ {ok , Pid } = start_link (default , true , true , CfgPath ),
11611170 try
11621171 Data = rand :bytes (512 ),
11631172 {ok , Encrypted } = encrypt (Pid , Data ),
@@ -1186,7 +1195,7 @@ upgrade_from_7_2_with_password_test() ->
11861195 undefined ,
11871196 fun (CfgPath ) ->
11881197 ok = file :write_file (DKeyPath , base64 :decode (DKeyNoPass )),
1189- {ok , Pid } = start_link (default , true , CfgPath ),
1198+ {ok , Pid } = start_link (default , true , true , CfgPath ),
11901199 try
11911200 Data = rand :bytes (512 ),
11921201 {ok , Encrypted } = encrypt (Pid , Data ),
@@ -1396,7 +1405,7 @@ with_gosecrets(Cfg, Fun, ResetMemorizePassword) ->
13961405 with_tmp_cfg (
13971406 Cfg ,
13981407 fun (CfgPath ) ->
1399- {ok , Pid } = start_link (default , true , CfgPath ),
1408+ {ok , Pid } = start_link (default , true , false , CfgPath ),
14001409 try
14011410 Fun (CfgPath , Pid )
14021411 after
0 commit comments