40 const string &password,
const string &challenge)
48 <<
": " << strerror(errno) << endl;
60 bool authenticated =
false;
62 if (pipe(authintercom) == -1) {
63 session.
setLastError(
"An error occurred when creating pipes: "
64 +
string(strerror(errno)));
68 if (pipe(intercomw) == -1) {
69 session.
setLastError(
"An error occurred when creating pipes: "
70 +
string(strerror(errno)));
71 close(authintercom[0]);
72 close(authintercom[1]);
76 if (pipe(intercomr) == -1) {
77 session.
setLastError(
"An error occurred when creating pipes: "
78 +
string(strerror(errno)));
81 close(authintercom[0]);
82 close(authintercom[1]);
89 if ((c = ctime(&t)) != 0) {
93 timestamp =
"unknown timestamp";
95 string pid = to_string(session.
getPid());
99 int childspid = fork();
100 if (childspid == -1) {
101 bincLog <<
"bincimap-up: pid " << pid
102 <<
" failed to start main server: "
103 << strerror(errno) << endl;
108 if (childspid == 0) {
109 close(authintercom[1]);
113 if (dup2(intercomr[1], 1) == -1) {
115 <<
" authenticate(), [auth module] dup2 failed: "
116 << strerror(errno) << endl;
121 if (dup2(intercomw[0], 0) == -1) {
123 <<
" authenticate(), [auth module] dup2 failed: "
124 << strerror(errno) << endl;
129 if (dup2(authintercom[0], 3) == -1) {
131 <<
" authenticate(), [auth module] dup2 failed: "
132 << strerror(errno) << endl;
140 <<
" authenticate(), [auth module] invocation of "
142 <<
" failed: " << strerror(errno) << endl;
147 bincLog <<
"bincimap-up: pid " << pid
148 <<
" missing mandatory -- in argument list,"
149 " after bincimap-up + arguments, before authenticator."
150 " Please check your run scripts and the man page bincimap(1) for"
151 " more on how to invoke Binc IMAP." << endl;
157 close(authintercom[0]);
160 int dataSize = username.length() + password.length() + challenge.length() + timestamp.length();
162 char *checkpasswordData =
new char[dataSize];
163 char *cpTmp = checkpasswordData;
164 strcpy(cpTmp, username.c_str());
165 cpTmp += username.length();
167 strcpy(cpTmp, password.c_str());
168 cpTmp += password.length();
171 strcpy(cpTmp, challenge.c_str());
172 cpTmp += challenge.length();
174 strcpy(cpTmp, timestamp.c_str());
175 cpTmp += timestamp.length();
179 <<
" authenticate(), writing username/password to "
183 signal(SIGPIPE, SIG_IGN);
184 int res = write(authintercom[1], checkpasswordData, dataSize);
185 delete[] checkpasswordData;
186 if (res != dataSize) {
188 <<
" error writing to authenticator "
190 << strerror(errno) << endl;
196 close(authintercom[1]);
202 FD_SET(fileno(stdin), &rmask);
203 FD_SET(intercomr[0], &rmask);
205 int maxfd = intercomr[0];
206 bool disconnected =
false;
207 bool timedout =
false;
213 struct timeval timeout;
218 timeout.tv_sec = IDLE_TIMEOUT + AUTH_PENALTY * AUTH_TIMEOUT;
226 n = select(maxfd + 1, &rtmp, 0, 0, &timeout);
227 }
while (n < 0 && errno == EINTR);
231 <<
" error: invalid exit from select, "
232 << strerror(errno) << endl;
237 bincLog <<
"bincimap-up: pid " << pid
238 <<
" server timed out after "
239 << IDLE_TIMEOUT <<
" seconds" << endl;
245 if (FD_ISSET(fileno(stdin), &rtmp)) {
246 authenticated =
true;
251 if (ret == 0 || ret == -1) {
260 if (ret == -2)
continue;
264 w = write(intercomw[1], data.c_str(), data.length());
265 }
while (w < 0 && errno == EINTR);
271 <<
" error writing to server: "
272 << strerror(errno) << endl;
278 if (FD_ISSET(intercomr[0], &rtmp)) {
280 int ret = read(intercomr[0], buf,
sizeof(buf));
285 }
else if (ret == -1) {
287 <<
" error reading from server: "
288 << strerror(errno) << endl;
305 if (waitpid(childspid, &result, 0) != childspid) {
306 bincLog <<
"bincimap-up: pid " << pid
307 <<
" <" << username <<
"> authentication failed: "
308 << (authenticated ?
"server " : session.
unparsedArgs[0])
309 <<
" waitpid returned unexpected value" << endl;
310 string tmp = strerror(errno);
317 if (timedout)
return 3;
319 if (disconnected)
return 0;
321 if (WIFSIGNALED(result)) {
322 bincLog <<
"bincimap-up: pid " << pid
323 <<
" <" << username <<
"> authentication failed: "
325 <<
" died by signal " << WTERMSIG(result) << endl;
333 <<
" authenticate() ,"
334 << (authenticated ?
"authenticator" :
"server")
335 <<
" exited with code " << WEXITSTATUS(result) << endl;
337 switch (WEXITSTATUS(result)) {
341 bincLog <<
"bincimap-up: pid " << pid
342 <<
" <" << username <<
"> failed to log in" << endl;
348 bincLog <<
"bincimap-up: pid " << pid
349 <<
" <" << username <<
"> authentication failed: "
350 << (authenticated ?
"authenticator" :
"server")
351 <<
" reports wrong usage" << endl;
356 bincLog <<
"bincimap-up: pid " << pid
357 <<
" <" << username <<
"> authentication failed: "
358 << (authenticated ?
"authenticator" :
"server")
359 <<
" returned " << WEXITSTATUS(result) << endl;
Declaration of the common authentication mechanism.
void setLastError(const std::string &error) const
void setUserID(const std::string &s)
static Session & getInstance(void)
Declaration of miscellaneous convertion functions.
Declaration of the IODevice class.
Declaration of the IOFactory class.
int authenticate(Depot &, const std::string &username, const std::string &password, const std::string &challenge)
void trim(std::string &s_in, const std::string &chars=" \t\r\n")