/[rdesktop]/sourceforge.net/trunk/rdesktop/readpass.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /sourceforge.net/trunk/rdesktop/readpass.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 97 - (hide annotations)
Fri Aug 9 11:55:39 2002 UTC (21 years, 10 months ago) by astrand
File MIME type: text/plain
File size: 3101 byte(s)
Closing unnecessary fds before askpass execution

1 astrand 96 /*
2     rdesktop: A Remote Desktop Protocol client.
3     User interface services - X keyboard mapping
4     Copyright (C) Matthew Chapman 1999-2001
5    
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21     #include <sys/types.h>
22     #include <signal.h>
23     #include <stdio.h>
24     #include <errno.h>
25     #include "rdesktop.h"
26     #include <assert.h>
27     #include <unistd.h>
28     #include <sys/wait.h>
29 astrand 97 #include <sys/stat.h>
30     #include <fcntl.h>
31 astrand 96
32     /* Execute specified askpass program and fetch password from standard
33     output. Return NULL on failure, otherwise a pointer to the data
34     read (which must be freed by caller) */
35    
36     char *
37     askpass(char *askpass, const char *msg)
38     {
39     pid_t pid;
40     size_t len;
41     char *pass;
42     int p[2], status, ret;
43     char buf[1024];
44 astrand 97 int devnull;
45 astrand 96
46     if (fflush(stdout) != 0)
47     error("askpass: fflush: %s", strerror(errno));
48     assert(askpass != NULL);
49     if (pipe(p) < 0)
50     {
51     error("askpass: pipe: %s", strerror(errno));
52     return NULL;
53     }
54    
55     pid = fork();
56     switch (pid)
57     {
58     case -1:
59     error("askpass: fork: %s", strerror(errno));
60     return NULL;
61     break;
62     case 0:
63     /* Child */
64     seteuid(getuid());
65     setuid(getuid());
66     /* Close read end */
67     close(p[0]);
68 astrand 97
69     /* Setup stdin */
70     devnull = open("/dev/null", 0, O_RDONLY);
71     if (dup2(devnull, STDIN_FILENO) < 0)
72     {
73     error("askpass: dup2: %s", strerror(errno));
74     exit(1);
75     }
76     close(devnull);
77    
78     /* Setup stdout */
79 astrand 96 if (dup2(p[1], STDOUT_FILENO) < 0)
80     {
81     error("askpass: dup2: %s", strerror(errno));
82     exit(1);
83     }
84 astrand 97 close(p[1]);
85    
86     /* By now, the following fds are open:
87     0 -> /dev/null
88     1 -> pipe write end
89     2 -> users terminal */
90 astrand 96 execlp(askpass, askpass, msg, (char *) 0);
91     error("askpass: exec(%s): %s", askpass, strerror(errno));
92     exit(1);
93     break;
94     default:
95     /* Parent */
96     break;
97     }
98     /* Close write end */
99     close(p[1]);
100    
101     len = ret = 0;
102     do
103     {
104     ret = read(p[0], buf + len, sizeof(buf) - 1 - len);
105    
106     if (ret == -1 && errno == EINTR)
107     continue;
108     if (ret <= 0)
109     break;
110    
111     len += ret;
112     }
113     while (sizeof(buf) - 1 - len > 0);
114    
115    
116     buf[len] = '\0';
117    
118     close(p[0]);
119     while (waitpid(pid, &status, 0) < 0)
120     if (errno != EINTR)
121     break;
122    
123     if (WIFEXITED(status))
124     {
125     if (WEXITSTATUS(status))
126     {
127     error("askpass program returned %d\n", WEXITSTATUS(status));
128     return NULL;
129     }
130     }
131     else
132     {
133     error("abnormal exit from askpass program");
134     return NULL;
135     }
136    
137     buf[strcspn(buf, "\r\n")] = '\0';
138     pass = strdup(buf);
139     memset(buf, 0, sizeof(buf));
140     return pass;
141     }

  ViewVC Help
Powered by ViewVC 1.1.26