MagickCore 7.0.10
passphrase.c
Go to the documentation of this file.
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% PPPP AAA SSSSS SSSSS PPPP H H RRRR AAA SSSSS EEEEE %
7% P P A A SS SS P P H H R R A A SS E %
8% PPPP AAAAA SSS SSS PPPP HHHHH RRRR AAAAA SSS EEE %
9% P A A SS SS P H H R R A A SS E %
10% P A A SSSSS SSSSS P H H R R A A SSSSS EEEEE %
11% %
12% %
13% Wizard's Toolkit Passphrase Methods %
14% %
15% Software Design %
16% Cristy %
17% March 2003 %
18% %
19% %
20% Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization %
21% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% https://imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39#include "wizard/studio.h"
40#include "wizard/exception.h"
42#include "wizard/memory_.h"
43#include "wizard/passphrase.h"
45#if defined(WIZARDSTOOLKIT_HAVE_TERMIOS_H)
46#include <termios.h>
47#endif
48
49/*
50 Define declarations.
51*/
52#ifdef TCSASOFT
53# define _T_FLUSH (TCSAFLUSH | TCSASOFT)
54#else
55# define _T_FLUSH (TCSAFLUSH)
56#endif
57
58#if !defined(_POSIX_VDISABLE) && defined(VDISABLE)
59# define _POSIX_VDISABLE VDISABLE
60#endif
61
62#define _PATH_TTY "/dev/tty"
63
64/*
65 Typedef declarations.
66*/
67typedef enum
68{
69 EchoOffMode = 0x00, /* Turn off echo (default). */
70 EchoOnMode = 0x01, /* Leave echo on. */
71 RequireTTYMode = 0x02, /* Fail if there is no tty. */
72 ForceLowerMode = 0x04, /* Force input to lower case. */
73 ForceUpperMode = 0x08, /* Force input to upper case. */
74 SevenBitMode = 0x10, /* Strip the high bit from input. */
75 StdinMode = 0x20 /* Read from stdin, not /dev/tty */
77
78/*
79 Global declarations.
80*/
81static volatile sig_atomic_t
83
84/*
85%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86% %
87% %
88% %
89% G e t P h r a s e %
90% %
91% %
92% %
93%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94%
95% GetPhrase() gets a phrase from the terminal.
96%
97% The format of the GetPhrase method is:
98%
99% WizardBooleanType GetPhrase(const char *prompt,PassphraseMode flags,
100% StringInfo *phrase)
101%
102% A description of each parameter follows:
103%
104% o prompt: Prompt the user for the passphrase.
105%
106% o flags: modify the behavior of this method by setting one or more of
107% these flags:
108%
109% EchoOffMode Turn off echo (default).
110% EchoOnMode Leave echo on.
111% RequireTTYMode Fail if there is no tty.
112% ForceLowerMode Force input to lower case.
113% ForceUpperMode Force input to upper case.
114% SevenBitMode Strip the high bit from input.
115% StdinMode Read from stdin, not /dev/tty.
116%
117% o phrase: The passphrase is returned in this buffer.
118%
119*/
120
121static void SignalHandler(int signal)
122{
123 signal_number=(sig_atomic_t) signal;
124}
125
126static WizardBooleanType GetPhrase(const char *prompt,PassphraseMode flags,
127 StringInfo *phrase)
128{
129 ssize_t
130 count;
131
132#if defined(WIZARDSTOOLKIT_HAVE_TERMIOS_H)
133 char
134 c;
135
136 int
137 input,
138 output;
139
140 unsigned char
141 *p;
142
143 struct sigaction
144 action,
145 sigalrm,
146 sighup,
147 sigint,
148 sigpipe,
149 sigquit,
150 sigterm,
151 sigtstp,
152 sigttin,
153 sigttou;
154
155 struct termios
156 attributes,
157 save_attributes;
158
159 /*
160 Read and write to _PATH_TTY if available, otherwise from stdin.
161 */
163 input=STDIN_FILENO;
164 output=STDERR_FILENO;
165 if ((flags & StdinMode) == 0)
166 {
167 input=open_utf8(_PATH_TTY,O_RDWR,0);
168 output=input;
169 }
170 if ((input == -1) || (output == -1))
171 return(WizardFalse);
172 if (((flags & StdinMode) != 0) && ((flags & RequireTTYMode) != 0))
173 {
174 errno=ENOTTY;
175 return(WizardFalse);
176 }
177 /*
178 Set our signal handler.
179 */
180 (void) sigemptyset(&action.sa_mask);
181 action.sa_flags=0; /* don't restart system calls */
182 action.sa_handler=SignalHandler;
183 (void) sigaction(SIGALRM,&action,&sigalrm);
184 (void) sigaction(SIGHUP,&action,&sighup);
185 (void) sigaction(SIGINT,&action,&sigint);
186 (void) sigaction(SIGPIPE,&action,&sigpipe);
187 (void) sigaction(SIGQUIT,&action,&sigquit);
188 (void) sigaction(SIGTERM,&action,&sigterm);
189 (void) sigaction(SIGTSTP,&action,&sigtstp);
190 (void) sigaction(SIGTTIN,&action,&sigttin);
191 (void) sigaction(SIGTTOU,&action,&sigttou);
192 if ((input == STDIN_FILENO) || (tcgetattr(input,&save_attributes) != 0))
193 {
194 (void) memset(&attributes,0,sizeof(attributes));
195 attributes.c_lflag|=ECHO;
196 (void) CopyWizardMemory(&save_attributes,&attributes,sizeof(attributes));
197 }
198 else
199 {
200 /*
201 Turn off echo.
202 */
203 (void) CopyWizardMemory(&attributes,&save_attributes,sizeof(attributes));
204 if ((flags & EchoOnMode) == 0)
205 attributes.c_lflag&=(~(ECHO | ECHONL));
206#if defined(VSTATUS)
207 if (attributes.c_cc[VSTATUS] != _POSIX_VDISABLE)
208 attributes.c_cc[VSTATUS]=_POSIX_VDISABLE;
209#endif
210 (void) tcsetattr(input,_T_FLUSH,&attributes);
211 }
212 if (((flags & StdinMode) == 0) && (output != -1))
213 count=write(output,prompt,strlen(prompt));
215 p=GetStringInfoDatum(phrase);
216 while (((count=read(input,&c,1)) == 1) && (c != '\n') && (c != '\r'))
217 {
218 if ((size_t) (p-GetStringInfoDatum(phrase)) <
219 (GetStringInfoLength(phrase)-1))
220 {
221 if ((flags & SevenBitMode) != 0)
222 c&=0x7f;
223 if (isalpha((int) c) != 0)
224 {
225 if ((flags & ForceLowerMode) != 0)
226 c=(char) tolower((int) c);
227 if ((flags & ForceUpperMode) != 0)
228 c=(char) toupper((int) c);
229 }
230 *p++=(unsigned char) c;
231 }
232 }
233 *p=(unsigned char) '\0';
234 SetStringInfoLength(phrase,(size_t) (p-GetStringInfoDatum(phrase)));
235 if ((attributes.c_lflag & ECHO) == 0)
236 count=write(output,"\n",1);
237 /*
238 Restore old terminal settings and signals.
239 */
240 if (memcmp(&attributes,&save_attributes,sizeof(attributes)) != 0)
241 (void) tcsetattr(input,_T_FLUSH,&save_attributes);
242 (void) sigaction(SIGALRM,&sigalrm,(struct sigaction *) NULL);
243 (void) sigaction(SIGHUP,&sighup,(struct sigaction *) NULL);
244 (void) sigaction(SIGINT,&sigint,(struct sigaction *) NULL);
245 (void) sigaction(SIGQUIT,&sigquit,(struct sigaction *) NULL);
246 (void) sigaction(SIGPIPE,&sigpipe,(struct sigaction *) NULL);
247 (void) sigaction(SIGTERM,&sigterm,(struct sigaction *) NULL);
248 (void) sigaction(SIGTSTP,&sigtstp,(struct sigaction *) NULL);
249 (void) sigaction(SIGTTIN,&sigttin,(struct sigaction *) NULL);
250 if (input != STDIN_FILENO)
251 input=close(input)-1;
252 if (signal_number != 0)
253 {
254 /*
255 We were interrupted by a signal.
256 */
257 (void) kill((pid_t) getpid(),(int) signal_number);
258 if ((signal_number == (sig_atomic_t) SIGTSTP) ||
259 (signal_number == (sig_atomic_t) SIGTTIN) ||
260 (signal_number == (sig_atomic_t) SIGTTOU))
261 return(GetPhrase(prompt,flags,phrase));
262 }
263#else
264 (void) fputs(prompt,stdout);
266 count=read(fileno(stdin),GetStringInfoDatum(phrase),WizardPathExtent);
267 SetStringInfoLength(phrase,count);
268#endif
269 return(count != -1 ? WizardTrue : WizardFalse);
270}
271
272/*
273%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274% %
275% %
276% %
277% G e t P a s s p h r a s e %
278% %
279% %
280% %
281%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282%
283% GetPassphrase() gets a passphrase from the terminal and returns it.
284%
285% The format of the GetPassphrase method is:
286%
287% StringInfo GetPassphrase(ExceptionInfo *exception)
288%
289% A description of each parameter follows:
290%
291% o prompt: Prompt the user for the passphrase.
292%
293*/
295{
296 char
297 prompt[WizardPathExtent];
298
300 status;
301
303 *phrase,
304 *rephrase;
305
309 "Enter the passphrase (maximum of %d characters)\n",WizardPathExtent);
310 status=write(STDERR_FILENO,prompt,strlen(prompt)) < 0 ? WizardFalse :
312 for ( ; ; )
313 {
314 status=GetPhrase("Enter passphrase: ",EchoOffMode,phrase);
315 if (status == WizardFalse)
316 {
317 (void) ThrowWizardException(exception,GetWizardModule(),
318 AuthenticateError,"unable to get pass phrase `%s'",strerror(errno));
319 return((StringInfo *) NULL);
320 }
321 status=GetPhrase("Enter same passphrase again: ",EchoOffMode,rephrase);
322 if (status == WizardFalse)
323 {
324 (void) ThrowWizardException(exception,GetWizardModule(),
325 AuthenticateError,"unable to get pass phrase `%s'",strerror(errno));
326 return((StringInfo *) NULL);
327 }
328 if (CompareStringInfo(phrase,rephrase) == 0)
329 break;
330 (void) PrintWizardString(stderr,"Passphrases are different. Try again.\n");
331 }
332 rephrase=DestroyStringInfo(rephrase);
334 return(phrase);
335}
WizardExport WizardBooleanType ThrowWizardException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *format,...)
Definition exception.c:1029
@ AuthenticateError
Definition exception.h:91
WizardExport ssize_t FormatLocaleString(char *string, const size_t length, const char *format,...)
Definition locale.c:465
#define GetWizardModule()
Definition log.h:30
WizardExport void * CopyWizardMemory(void *destination, const void *source, const size_t size)
Definition memory.c:700
#define WizardExport
#define WizardPathExtent
static WizardBooleanType GetPhrase(const char *prompt, PassphraseMode flags, StringInfo *phrase)
Definition passphrase.c:126
#define _T_FLUSH
Definition passphrase.c:55
static volatile sig_atomic_t signal_number
Definition passphrase.c:82
WizardExport StringInfo * GetPassphrase(ExceptionInfo *exception)
Definition passphrase.c:294
PassphraseMode
Definition passphrase.c:68
@ StdinMode
Definition passphrase.c:75
@ EchoOnMode
Definition passphrase.c:70
@ ForceLowerMode
Definition passphrase.c:72
@ SevenBitMode
Definition passphrase.c:74
@ RequireTTYMode
Definition passphrase.c:71
@ ForceUpperMode
Definition passphrase.c:73
@ EchoOffMode
Definition passphrase.c:69
#define _PATH_TTY
Definition passphrase.c:62
WizardExport void SetStringInfoLength(StringInfo *string_info, const size_t length)
Definition string.c:1865
WizardExport size_t GetStringInfoLength(const StringInfo *string_info)
Definition string.c:1280
WizardExport StringInfo * AcquireStringInfo(const size_t length)
Definition string.c:179
WizardExport int CompareStringInfo(const StringInfo *target, const StringInfo *source)
Definition string.c:372
WizardExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition string.c:1251
WizardExport ssize_t PrintWizardString(FILE *file, const char *format,...)
Definition string.c:1668
WizardExport StringInfo * DestroyStringInfo(StringInfo *string_info)
Definition string.c:857
#define STDERR_FILENO
Definition studio.h:322
#define STDIN_FILENO
Definition studio.h:314
static int open_utf8(const char *path, int flags, mode_t mode)
WizardBooleanType
Definition wizard-type.h:26
@ WizardTrue
Definition wizard-type.h:28
@ WizardFalse
Definition wizard-type.h:27
WIZARDSTOOLKIT_RETSIGTYPE SignalHandler(int)
Definition wizard.c:77