/* $Id: pswd.c,v 1.1 2004/12/07 15:12:38 cinar Exp $ * * pswd.c: is a simple program which emulates the password * encryption/encoding process done by LabView HTTP Server * (part of G Server)'s sub-vi named "Pswd Encode Password.vi" * * Copyright (c) 2003 Ali Onur Cinar * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. And also * please DO NOT REMOVE my name, and give me a CREDIT when you use * whole or a part of this program in an other program. * * To compile: * using GNU C Compiler : gcc pswd.c -lieee * using Intel C++ Compiler : icc -mp pswd.c -lieee * * Tested on Linux using GNU C Compiler 3.2, Intel C++ Compiler 7.1 * */ #include #include #include #include #include #include static inline unsigned char rotate (const unsigned char c) { return (c << 1) | ((c & 0x80) >> 7); } static void copy (unsigned char* s, unsigned char* t, int c) { int i; for (i=0; i<=c; i++) t[i] = s[i]; } static void reverse (unsigned char* s, int c) { int i; unsigned char *t; assert((t = (unsigned char*) malloc(c+1)) != NULL); copy (s,t,c); for (i=c; i>=0; i--) s[i] = t[c-i]; free(t); } typedef struct __pswd_pack { char *user; char *pass; unsigned char enc[19]; } pswd_pack; void pswd_encode (pswd_pack *p) { /* vars */ char *pwd; unsigned char *key, *key1, *key2, *key3, *key4; int i,j; /* for casting */ union dbits { double d; unsigned char s[8]; } ac; /* force IEEE 754 compatibility */ assert(_LIB_VERSION == _IEEE_); /* check user and pass sizes */ assert(strlen(p->user) >= 2); assert(strlen(p->pass) <= 126); /* combine pass and user (pass + first 2 letter of user ) */ assert((pwd = (char*) malloc(strlen(p->pass)+2)) != NULL); memset(pwd,0,strlen(p->pass)+2); strcpy(pwd,p->pass); strncat(pwd,p->user,2); /* fill key block */ assert((key = (unsigned char*) malloc(128)) != NULL); for (i=0; i<128; i++) key[i] = pwd[i % strlen(pwd)]; free(pwd); /* accumulate */ for (i=0,ac.d=0.0; i<128; i++) ac.d = (ac.d * M_PI_2) + key[i]; free(key); /* cast double to unsigned char array */ key1 = ac.s; #if __BYTE_ORDER == __LITTLE_ENDIAN /* to big endian */ reverse(key1,7); #endif /* rotate */ assert((key2 = (unsigned char*) malloc(8)) != NULL); for (i=0; i<8; i++) key2[i] = rotate(key1[i]); /* reverse */ assert((key3 = (unsigned char*) malloc(8)) != NULL); copy(key1,key3,7); reverse(key3,7); /* xor */ assert((key4 = (unsigned char*) malloc(8)) != NULL); for (i=0; i<8; i++) key4[i] = (key1[i] ^ key2[i]) ^ key3[i]; free(key2); free(key3); /* combine user and enc */ strncpy((char*) p->enc,p->user,2); /* enc */ for (i=0,j=2; i<8; i++,j+=2) { p->enc[j] = ('a'+i) + (key4[i] & 7); p->enc[j+1] = ('a'+i) + ((key4[i] >> 4)); } free(key4); /* terminate enc */ p->enc[18] = '\0'; } int main (int argc, char **argv) { pswd_pack p; /* test 1 */ p.user = "cinar"; p.pass = "onur"; pswd_encode(&p); printf("Checking (%s)... %s\n",p.enc, (strcmp("cibgbjheknemjtnvnr",(char*) p.enc) == 0) ? "ok" : "failed"); return(0); }