~ubuntu-branches/ubuntu/lucid/sudo/lucid-proposed

« back to all changes in this revision

Viewing changes to tgetpass.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc Deslauriers
  • Date: 2010-02-08 18:47:06 UTC
  • mfrom: (1.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20100208184706-kqgmuj0qe7telzq3
Tags: 1.7.2p1-1ubuntu1
* Merge from debian testing.  Remaining changes:
 - debian/rules: Disable lecture, enable tty_tickets by default. (Ubuntu
   specific)
 - Add debian/sudo_root.8: Explanation of root handling through sudo.
   Install it in debian/rules. (Ubuntu specific)
 - sudo.c: If the user successfully authenticated and he is in the 'admin'
   group, then create a stamp ~/.sudo_as_admin_successful. Our default bash
   profile checks for this and displays a short intro about sudo if the
   flag is not present. (Ubuntu specific)
 - env.c: Add "http_proxy" to initial_keepenv_table, so that it is kept
   for "sudo apt-get ...". (Ubuntu specific EBW hack, should disappear at
   some point)
 - debian/{rules,postinst,sudo-ldap.postinst}: Disable init script
   installation. Debian reintroduced it because /var/run tmpfs is not the
   default there, but has been on Ubuntu for ages.
 - debian/{source_sudo.py,rules,sudo-ldap.dirs,sudo.dirs}: Add apport hook

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 1996, 1998-2005, 2007-2008
 
2
 * Copyright (c) 1996, 1998-2005, 2007-2009
3
3
 *      Todd C. Miller <Todd.Miller@courtesan.com>
4
4
 *
5
5
 * Permission to use, copy, modify, and distribute this software for any
27
27
 
28
28
#include <sys/types.h>
29
29
#include <sys/param.h>
30
 
#ifdef HAVE_SYS_BSDTYPES_H
31
 
# include <sys/bsdtypes.h>
32
 
#endif /* HAVE_SYS_BSDTYPES_H */
33
 
#include <sys/time.h>
34
30
#include <stdio.h>
35
31
#ifdef STDC_HEADERS
36
32
# include <stdlib.h>
57
53
#include <errno.h>
58
54
#include <signal.h>
59
55
#include <fcntl.h>
60
 
#ifdef HAVE_TERMIOS_H
61
 
# include <termios.h>
62
 
#else
63
 
# ifdef HAVE_TERMIO_H
64
 
#  include <termio.h>
65
 
# else
66
 
#  include <sgtty.h>
67
 
#  include <sys/ioctl.h>
68
 
# endif /* HAVE_TERMIO_H */
69
 
#endif /* HAVE_TERMIOS_H */
70
56
 
71
57
#include "sudo.h"
72
58
 
73
59
#ifndef lint
74
 
__unused static const char rcsid[] = "$Sudo: tgetpass.c,v 1.126 2008/12/09 20:55:49 millert Exp $";
 
60
__unused static const char rcsid[] = "$Sudo: tgetpass.c,v 1.131 2009/05/25 12:02:42 millert Exp $";
75
61
#endif /* lint */
76
62
 
77
 
#ifndef TCSASOFT
78
 
# define TCSASOFT       0
79
 
#endif
80
 
#ifndef ECHONL
81
 
# define ECHONL 0
82
 
#endif
83
 
 
84
 
#ifndef _POSIX_VDISABLE
85
 
# ifdef VDISABLE
86
 
#  define _POSIX_VDISABLE       VDISABLE
87
 
# else
88
 
#  define _POSIX_VDISABLE       0
89
 
# endif
90
 
#endif
91
 
 
92
 
/*
93
 
 * Compat macros for non-termios systems.
94
 
 */
95
 
#ifndef HAVE_TERMIOS_H
96
 
# ifdef HAVE_TERMIO_H
97
 
#  undef termios
98
 
#  define termios               termio
99
 
#  define tcgetattr(f, t)       ioctl(f, TCGETA, t)
100
 
#  define tcsetattr(f, a, t)    ioctl(f, a, t)
101
 
#  undef TCSAFLUSH
102
 
#  define TCSAFLUSH             TCSETAF
103
 
# else
104
 
#  undef termios
105
 
#  define termios               sgttyb
106
 
#  define c_lflag               sg_flags
107
 
#  define tcgetattr(f, t)       ioctl(f, TIOCGETP, t)
108
 
#  define tcsetattr(f, a, t)    ioctl(f, a, t)
109
 
#  undef TCSAFLUSH
110
 
#  define TCSAFLUSH             TIOCSETP
111
 
# endif /* HAVE_TERMIO_H */
112
 
#endif /* HAVE_TERMIOS_H */
113
 
 
114
63
static volatile sig_atomic_t signo;
115
64
 
116
65
static void handler __P((int));
117
 
static char *getln __P((int, char *, size_t));
 
66
static char *getln __P((int, char *, size_t, int));
118
67
static char *sudo_askpass __P((const char *));
119
68
 
 
69
extern int term_restore __P((int));
 
70
extern int term_noecho __P((int));
 
71
extern int term_raw __P((int));
 
72
 
120
73
/*
121
74
 * Like getpass(3) but with timeout and echo flags.
122
75
 */
128
81
{
129
82
    sigaction_t sa, savealrm, saveint, savehup, savequit, saveterm;
130
83
    sigaction_t savetstp, savettin, savettou;
131
 
    struct termios term, oterm;
132
84
    char *pass;
133
85
    static char buf[SUDO_PASS_MAX + 1];
134
 
    int input, output, save_errno;
 
86
    int input, output, save_errno, neednl;;
135
87
 
136
88
    (void) fflush(stdout);
137
89
 
167
119
    (void) sigaction(SIGTTIN, &sa, &savettin);
168
120
    (void) sigaction(SIGTTOU, &sa, &savettou);
169
121
 
170
 
    /* Turn echo off/on as specified by flags.  */
171
 
    if (tcgetattr(input, &oterm) == 0) {
172
 
        (void) memcpy(&term, &oterm, sizeof(term));
173
 
        if (!ISSET(flags, TGP_ECHO))
174
 
            CLR(term.c_lflag, ECHO|ECHONL);
175
 
#ifdef VSTATUS
176
 
        term.c_cc[VSTATUS] = _POSIX_VDISABLE;
177
 
#endif
178
 
        (void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
179
 
    } else {
180
 
        zero_bytes(&term, sizeof(term));
181
 
        zero_bytes(&oterm, sizeof(oterm));
182
 
    }
 
122
    if (def_pwfeedback)
 
123
        neednl = term_raw(input);
 
124
    else
 
125
        neednl = term_noecho(input);
183
126
 
184
127
    /* No output if we are already backgrounded. */
185
128
    if (signo != SIGTTOU && signo != SIGTTIN) {
188
131
 
189
132
        if (timeout > 0)
190
133
            alarm(timeout);
191
 
        pass = getln(input, buf, sizeof(buf));
 
134
        pass = getln(input, buf, sizeof(buf), def_pwfeedback);
192
135
        alarm(0);
193
136
        save_errno = errno;
194
137
 
195
 
        if (!ISSET(term.c_lflag, ECHO))
 
138
        if (neednl)
196
139
            (void) write(output, "\n", 1);
197
140
    }
198
141
 
199
142
    /* Restore old tty settings and signals. */
200
 
    if (memcmp(&term, &oterm, sizeof(term)) != 0) {
201
 
        while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 &&
202
 
            errno == EINTR)
203
 
            continue;
204
 
    }
 
143
    term_restore(input);
205
144
    (void) sigaction(SIGALRM, &savealrm, NULL);
206
145
    (void) sigaction(SIGINT, &saveint, NULL);
207
146
    (void) sigaction(SIGHUP, &savehup, NULL);
269
208
 
270
209
    /* Get response from child (askpass) and restore SIGPIPE handler */
271
210
    (void) close(pfd[1]);
272
 
    pass = getln(pfd[0], buf, sizeof(buf));
 
211
    pass = getln(pfd[0], buf, sizeof(buf), 0);
273
212
    (void) close(pfd[0]);
274
213
    (void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
275
214
 
276
215
    return(pass);
277
216
}
278
217
 
 
218
extern int term_erase, term_kill;
 
219
 
279
220
static char *
280
 
getln(fd, buf, bufsiz)
 
221
getln(fd, buf, bufsiz, feedback)
281
222
    int fd;
282
223
    char *buf;
283
224
    size_t bufsiz;
 
225
    int feedback;
284
226
{
 
227
    size_t left = bufsiz;
285
228
    ssize_t nr = -1;
286
229
    char *cp = buf;
287
230
    char c = '\0';
288
231
 
289
 
    if (bufsiz == 0) {
 
232
    if (left == 0) {
290
233
        errno = EINVAL;
291
234
        return(NULL);                   /* sanity */
292
235
    }
293
236
 
294
 
    while (--bufsiz) {
 
237
    while (--left) {
295
238
        nr = read(fd, &c, 1);
296
239
        if (nr != 1 || c == '\n' || c == '\r')
297
240
            break;
 
241
        if (feedback) {
 
242
            if (c == term_kill) {
 
243
                while (cp > buf) {
 
244
                    (void) write(fd, "\b \b", 3);
 
245
                    --cp;
 
246
                }
 
247
                left = bufsiz;
 
248
                continue;
 
249
            } else if (c == term_erase) {
 
250
                if (cp > buf) {
 
251
                    (void) write(fd, "\b \b", 3);
 
252
                    --cp;
 
253
                    left++;
 
254
                }
 
255
                continue;
 
256
            }
 
257
            (void) write(fd, "*", 1);
 
258
        }
298
259
        *cp++ = c;
299
260
    }
300
261
    *cp = '\0';
 
262
    if (feedback) {
 
263
        /* erase stars */
 
264
        while (cp > buf) {
 
265
            (void) write(fd, "\b \b", 3);
 
266
            --cp;
 
267
        }
 
268
    }
301
269
 
302
270
    return(nr == 1 ? buf : NULL);
303
271
}