00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #define nil 0
00019 #define crypt CRYPT
00020 #include <sys/types.h>
00021 #include <pwd.h>
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <unistd.h>
00026
00027 #define LEN 1024
00028 char SHADOW[] = "/etc/shadow";
00029
00030 int main(int argc, char **argv)
00031 {
00032 char key[LEN];
00033 char *salt;
00034 struct passwd *pw;
00035 int n;
00036
00037
00038
00039
00040 n= read(0, key, LEN);
00041 if (n < 0) return 1;
00042 salt = key + n;
00043 n = 0;
00044 while (salt > key) if (*--salt == 0) n++;
00045 if (n != 2) return 1;
00046 salt = key + strlen(key) + 1;
00047
00048 if (salt[0] == '#' && salt[1] == '#') {
00049
00050
00051
00052 setpwfile(SHADOW);
00053
00054 if ((pw= getpwnam(salt + 2)) == nil) return 2;
00055
00056
00057
00058
00059 if (*pw->pw_passwd == 0 && *key == 0) {
00060
00061 } else
00062 if (strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd) != 0) {
00063 return 2;
00064 }
00065 } else {
00066
00067 if (*salt == 0 && *key == 0) {
00068
00069 } else {
00070 salt= crypt(key, salt);
00071 }
00072 }
00073
00074
00075 if (write(1, salt, strlen(salt) + 1) < 0) return 1;
00076 return 0;
00077 }
00078
00079
00080
00081
00082
00083
00084
00085 struct block {
00086 unsigned char b_data[64];
00087 };
00088
00089 struct ordering {
00090 unsigned char o_data[64];
00091 };
00092
00093 static struct block key;
00094
00095 static struct ordering InitialTr = {
00096 58,50,42,34,26,18,10, 2,60,52,44,36,28,20,12, 4,
00097 62,54,46,38,30,22,14, 6,64,56,48,40,32,24,16, 8,
00098 57,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3,
00099 61,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 7,
00100 };
00101
00102 static struct ordering FinalTr = {
00103 40, 8,48,16,56,24,64,32,39, 7,47,15,55,23,63,31,
00104 38, 6,46,14,54,22,62,30,37, 5,45,13,53,21,61,29,
00105 36, 4,44,12,52,20,60,28,35, 3,43,11,51,19,59,27,
00106 34, 2,42,10,50,18,58,26,33, 1,41, 9,49,17,57,25,
00107 };
00108
00109 static struct ordering swap = {
00110 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
00111 49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
00112 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,
00113 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,
00114 };
00115
00116 static struct ordering KeyTr1 = {
00117 57,49,41,33,25,17, 9, 1,58,50,42,34,26,18,
00118 10, 2,59,51,43,35,27,19,11, 3,60,52,44,36,
00119 63,55,47,39,31,23,15, 7,62,54,46,38,30,22,
00120 14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4,
00121 };
00122
00123 static struct ordering KeyTr2 = {
00124 14,17,11,24, 1, 5, 3,28,15, 6,21,10,
00125 23,19,12, 4,26, 8,16, 7,27,20,13, 2,
00126 41,52,31,37,47,55,30,40,51,45,33,48,
00127 44,49,39,56,34,53,46,42,50,36,29,32,
00128 };
00129
00130 static struct ordering etr = {
00131 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
00132 8, 9,10,11,12,13,12,13,14,15,16,17,
00133 16,17,18,19,20,21,20,21,22,23,24,25,
00134 24,25,26,27,28,29,28,29,30,31,32, 1,
00135 };
00136
00137 static struct ordering ptr = {
00138 16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,
00139 2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25,
00140 };
00141
00142 static unsigned char s_boxes[8][64] = {
00143 { 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
00144 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
00145 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
00146 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
00147 },
00148
00149 { 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
00150 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
00151 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
00152 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
00153 },
00154
00155 { 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
00156 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
00157 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
00158 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
00159 },
00160
00161 { 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
00162 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
00163 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
00164 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
00165 },
00166
00167 { 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
00168 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
00169 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
00170 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
00171 },
00172
00173 { 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
00174 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
00175 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
00176 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
00177 },
00178
00179 { 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
00180 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
00181 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
00182 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
00183 },
00184
00185 { 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
00186 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
00187 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
00188 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
00189 },
00190 };
00191
00192 static int rots[] = {
00193 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
00194 };
00195
00196 static void transpose(struct block *data, struct ordering *t, int n)
00197 {
00198 struct block x;
00199
00200 x = *data;
00201
00202 while (n-- > 0) {
00203 data->b_data[n] = x.b_data[t->o_data[n] - 1];
00204 }
00205 }
00206
00207 static void rotate(struct block *key)
00208 {
00209 unsigned char *p = key->b_data;
00210 unsigned char *ep = &(key->b_data[55]);
00211 int data0 = key->b_data[0], data28 = key->b_data[28];
00212
00213 while (p++ < ep) *(p-1) = *p;
00214 key->b_data[27] = data0;
00215 key->b_data[55] = data28;
00216 }
00217
00218 static struct ordering *EP = &etr;
00219
00220 static void f(int i, struct block *key, struct block *a, struct block *x)
00221 {
00222 struct block e, ikey, y;
00223 int k;
00224 unsigned char *p, *q, *r;
00225
00226 e = *a;
00227 transpose(&e, EP, 48);
00228 for (k = rots[i]; k; k--) rotate(key);
00229 ikey = *key;
00230 transpose(&ikey, &KeyTr2, 48);
00231 p = &(y.b_data[48]);
00232 q = &(e.b_data[48]);
00233 r = &(ikey.b_data[48]);
00234 while (p > y.b_data) {
00235 *--p = *--q ^ *--r;
00236 }
00237 q = x->b_data;
00238 for (k = 0; k < 8; k++) {
00239 int xb, r;
00240
00241 r = *p++ << 5;
00242 r += *p++ << 3;
00243 r += *p++ << 2;
00244 r += *p++ << 1;
00245 r += *p++;
00246 r += *p++ << 4;
00247
00248 xb = s_boxes[k][r];
00249
00250 *q++ = (xb >> 3) & 1;
00251 *q++ = (xb>>2) & 1;
00252 *q++ = (xb>>1) & 1;
00253 *q++ = (xb & 1);
00254 }
00255 transpose(x, &ptr, 32);
00256 }
00257
00258 static void setkey(char *k)
00259 {
00260
00261 key = *((struct block *) k);
00262 transpose(&key, &KeyTr1, 56);
00263 }
00264
00265 static void encrypt(char *blck, int edflag)
00266 {
00267 struct block *p = (struct block *) blck;
00268 int i;
00269
00270 transpose(p, &InitialTr, 64);
00271 for (i = 15; i>= 0; i--) {
00272 int j = edflag ? i : 15 - i;
00273 int k;
00274 struct block b, x;
00275
00276 b = *p;
00277 for (k = 31; k >= 0; k--) {
00278 p->b_data[k] = b.b_data[k + 32];
00279 }
00280 f(j, &key, p, &x);
00281 for (k = 31; k >= 0; k--) {
00282 p->b_data[k+32] = b.b_data[k] ^ x.b_data[k];
00283 }
00284 }
00285 transpose(p, &swap, 64);
00286 transpose(p, &FinalTr, 64);
00287 }
00288
00289 char *crypt(const char *pw, const char *salt)
00290 {
00291 char pwb[66];
00292 char *cp;
00293 static char result[16];
00294 char *p = pwb;
00295 struct ordering new_etr;
00296 int i;
00297
00298 while (*pw && p < &pwb[64]) {
00299 int j = 7;
00300
00301 while (j--) {
00302 *p++ = (*pw >> j) & 01;
00303 }
00304 pw++;
00305 *p++ = 0;
00306 }
00307 while (p < &pwb[64]) *p++ = 0;
00308
00309 setkey(p = pwb);
00310
00311 while (p < &pwb[66]) *p++ = 0;
00312
00313 new_etr = etr;
00314 EP = &new_etr;
00315 if (salt[0] == 0 || salt[1] == 0) salt = "**";
00316 for (i = 0; i < 2; i++) {
00317 char c = *salt++;
00318 int j;
00319
00320 result[i] = c;
00321 if ( c > 'Z') c -= 6 + 7 + '.';
00322 else if ( c > '9') c -= 7 + '.';
00323 else c -= '.';
00324
00325 for (j = 0; j < 6; j++) {
00326 if ((c >> j) & 01) {
00327 int t = 6*i + j;
00328 int temp = new_etr.o_data[t];
00329 new_etr.o_data[t] = new_etr.o_data[t+24];
00330 new_etr.o_data[t+24] = temp;
00331 }
00332 }
00333 }
00334
00335 if (result[1] == 0) result[1] = result[0];
00336
00337 for (i = 0; i < 25; i++) encrypt(pwb,0);
00338 EP = &etr;
00339
00340 p = pwb;
00341 cp = result+2;
00342 while (p < &pwb[66]) {
00343 int c = 0;
00344 int j = 6;
00345
00346 while (j--) {
00347 c <<= 1;
00348 c |= *p++;
00349 }
00350 c += '.';
00351 if (c > '9') c += 7;
00352 if (c > 'Z') c += 6;
00353 *cp++ = c;
00354 }
00355 *cp = 0;
00356 return result;
00357 }