00001
00002
00003
00004
00005
00006 #define nil ((void*)0)
00007 #define pipe _pipe
00008 #define fork _fork
00009 #define close _close
00010 #define dup2 _dup2
00011 #define execl _execl
00012 #define read _read
00013 #define _exit __exit
00014 #define write _write
00015 #define waitpid _waitpid
00016 #include <sys/types.h>
00017 #include <unistd.h>
00018 #include <string.h>
00019 #include <stdio.h>
00020 #include <errno.h>
00021 #include <stdarg.h>
00022 #include <sys/wait.h>
00023
00024
00025 static char PWDAUTH[] = "/usr/lib/pwdauth";
00026 #define LEN 1024
00027
00028 static void tell(const char *s0, ...)
00029 {
00030 va_list ap;
00031 const char *s;
00032
00033 va_start(ap, s0);
00034 s= s0;
00035 while (s != nil) {
00036 (void) write(2, s, strlen(s));
00037 s= va_arg(ap, const char *);
00038 }
00039 va_end(ap);
00040 }
00041
00042 char *crypt(const char *key, const char *salt)
00043 {
00044 pid_t pid;
00045 int status;
00046 int pfd[2];
00047 static char pwdata[LEN];
00048 char *p= pwdata;
00049 const char *k= key;
00050 const char *s= salt;
00051 int n;
00052
00053
00054 while ((*p++ = *k++) != 0) if (p == pwdata+LEN-1) goto fail;
00055 while ((*p++ = *s++) != 0) if (p == pwdata+LEN-0) goto fail;
00056
00057 if (pipe(pfd) < 0) goto fail;
00058
00059
00060 (void) write(pfd[1], pwdata, p - pwdata);
00061
00062 switch ((pid= fork())) {
00063 case -1:
00064 close(pfd[0]);
00065 close(pfd[1]);
00066 goto fail;
00067 case 0:
00068
00069 if (pfd[0] != 0) {
00070 dup2(pfd[0], 0);
00071 close(pfd[0]);
00072 }
00073 if (pfd[1] != 1) {
00074 dup2(pfd[1], 1);
00075 close(pfd[1]);
00076 }
00077
00078 execl(PWDAUTH, PWDAUTH, (char *) nil);
00079
00080 tell("crypt(): ", PWDAUTH, ": ", strerror(errno), "\r\n",
00081 (char *) nil);
00082
00083 (void) read(0, pwdata, LEN);
00084 _exit(1);
00085 }
00086 close(pfd[1]);
00087
00088 status= -1;
00089 while (waitpid(pid, &status, 0) == -1 && errno == EINTR) {}
00090 if (status != 0) {
00091 close(pfd[0]);
00092 goto fail;
00093 }
00094
00095
00096
00097
00098 n= read(pfd[0], pwdata, LEN);
00099 close(pfd[0]);
00100 if (n < 0) goto fail;
00101 p = pwdata + n;
00102 n = 0;
00103 while (p > pwdata) if (*--p == 0) n++;
00104 if (n != 1) goto fail;
00105 return pwdata;
00106
00107 fail:
00108 pwdata[0] = salt[0] ^ 1;
00109 pwdata[1] = 0;
00110 return pwdata;
00111 }
00112
00113
00114
00115