| ␉char * password;␊ |
| } User;␊ |
| ␊ |
| DB * initDBStruct()␊ |
| DB initDBStruct()␊ |
| {␊ |
| ␉DB * d = (DB *)malloc(sizeof(*d));␊ |
| ␉memset(d->dbhost, '\0', 255);␊ |
| ␉memset(d->dbname, '\0', 255);␊ |
| ␉memset(d->dbuser, '\0', 255);␊ |
| ␉memset(d->dbpass, '\0', 255);␊ |
| ␉memset(d->dbtable, '\0', 255);␊ |
| ␉strcpy(d->passfield, "password");␊ |
| ␉strcpy(d->otpfield, "otpkey");␊ |
| ␉d->dbport = 3306;␊ |
| ␉d->type = UNDEFINEDDB;␊ |
| ␉//DB * d = (DB *)malloc(sizeof(*d));␊ |
| ␉DB d;␊ |
| ␉memset(d.dbhost, '\0', 255);␊ |
| ␉memset(d.dbname, '\0', 255);␊ |
| ␉memset(d.dbuser, '\0', 255);␊ |
| ␉memset(d.dbpass, '\0', 255);␊ |
| ␉memset(d.dbtable, '\0', 255);␊ |
| ␉strcpy(d.passfield, "password");␊ |
| ␉strcpy(d.otpfield, "otpkey");␊ |
| ␉d.dbport = 3306;␊ |
| ␉d.type = UNDEFINEDDB;␊ |
| ␉return d;␊ |
| }␊ |
| ␊ |
| User * initUserStruct()␊ |
| User initUserStruct()␊ |
| {␊ |
| ␉User * u = (User *)malloc(sizeof(*u));␊ |
| ␉u->otp = NULL;␊ |
| ␉u->password = NULL;␊ |
| ␉u->user = NULL;␊ |
| ␉//User * u = (User *)malloc(sizeof(*u));␊ |
| ␉User u;␊ |
| ␉u.otp = NULL;␊ |
| ␉u.password = NULL;␊ |
| ␉u.user = NULL;␊ |
| ␉return u;␊ |
| }␊ |
| ␊ |
| User * getMySQLUser(char * user, DB * db)␊ |
| User getMySQLUser(char * user, DB db)␊ |
| {␊ |
| ␉char q[512];␊ |
| char q2[512];␊ |
| ␉int strp = 0;␊ |
| ␉MYSQL_RES *result;␊ |
| ␉MYSQL_ROW row;␊ |
| ␉User * u;␊ |
| ␉User u;␊ |
| ␉MYSQL *con;␊ |
| ␉memset(q, '\0', 512);␊ |
| ␉if (db->type != MYSQLDB)␊ |
| ␉␉return NULL;␊ |
| ␉if (db.type != MYSQLDB)␊ |
| ␉␉return u;␊ |
| ␉con = mysql_init(NULL);␊ |
| ␉u = initUserStruct();␊ |
| ␊ |
| ␉if (con == NULL) ␊ |
| ␉{␊ |
| ␉␉fprintf(stderr, "%s\n", mysql_error(con));␊ |
| ␉␉free(u);␊ |
| ␉␉return NULL;␊ |
| ␉␉//free(u);␊ |
| ␉␉return u;␊ |
| ␉}␊ |
| ␊ |
| ␉if (mysql_real_connect(con, db->dbhost, db->dbuser, db->dbpass, db->dbname,␊ |
| ␉␉db->dbport, NULL, 0) == NULL) ␊ |
| ␉if (mysql_real_connect(con, db.dbhost, db.dbuser, db.dbpass, db.dbname,␊ |
| ␉␉db.dbport, NULL, 0) == NULL) ␊ |
| ␉{␊ |
| ␉␉fprintf(stderr, "%s\n", mysql_error(con));␊ |
| ␉␉mysql_close(con);␊ |
| ␉␉free(u);␊ |
| ␉␉return NULL;␊ |
| ␉␉//free(u);␊ |
| ␉␉return u;␊ |
| ␉}␊ |
| ␊ |
| ␉strncpy(q, "SELECT ", 7);␊ |
| ␉strp += 7;␊ |
| ␉strncpy(q + strp, db->passfield, strlen(db->passfield));␊ |
| ␉strp += strlen(db->passfield);␊ |
| ␉strncpy(q + strp, db.passfield, strlen(db.passfield));␊ |
| ␉strp += strlen(db.passfield);␊ |
| ␉strncpy(q + strp, ",", 1);␊ |
| ␉strp += 1;␊ |
| ␉strncpy(q + strp, db->otpfield, strlen(db->otpfield));␊ |
| ␉strp += strlen(db->otpfield);␊ |
| ␉strncpy(q + strp, db.otpfield, strlen(db.otpfield));␊ |
| ␉strp += strlen(db.otpfield);␊ |
| ␉strncpy(q + strp, " FROM ", 6);␊ |
| ␉strp += 6;␊ |
| ␉strncpy(q + strp, db->dbtable, strlen(db->dbtable));␊ |
| ␉strp += strlen(db->dbtable);␊ |
| ␉strncpy(q + strp, db.dbtable, strlen(db.dbtable));␊ |
| ␉strp += strlen(db.dbtable);␊ |
| ␉strncpy(q + strp, " WHERE login = '", 16);␊ |
| ␉strp += 16;␊ |
| ␉mysql_real_escape_string(con, q2, user, strlen(user));␊ |
|
| ␉if (mysql_query(con, q) > 0)␊ |
| ␉{␊ |
| ␉␉mysql_close(con);␊ |
| ␉␉free(u);␊ |
| ␉␉return NULL;␊ |
| ␉␉//free(u);␊ |
| ␉␉return u;␊ |
| ␉}␊ |
| ␊ |
| ␉result = mysql_store_result(con);␊ |
| ␉if (result == 0)␊ |
| ␉{␊ |
| ␉␉mysql_close(con);␊ |
| ␉␉free(u);␊ |
| ␉␉return NULL;␊ |
| ␉␉//free(u);␊ |
| ␉␉return u;␊ |
| ␉}␉␊ |
| ␉row = mysql_fetch_row(result);␊ |
| ␉if (row != NULL)␊ |
| ␉{␊ |
| ␉␉u->user = user;␊ |
| ␉␉u->password = row[0];␊ |
| ␉␉u.user = user;␊ |
| ␉␉u.password = malloc( sizeof(char) * 255);␊ |
| ␉␉strcpy(u.password, row[0]);␊ |
| ␉} else {␊ |
| ␉␉mysql_free_result(result);␊ |
| ␉␉mysql_close(con);␊ |
| free(u);␊ |
| ␉␉return NULL;␊ |
| //free(u);␊ |
| ␉␉return u;␊ |
| ␉}␊ |
| ␉if (strcmp(row[1], "") != 0)␊ |
| ␉␉u->otp = row[1];␊ |
| ␉{␊ |
| ␉␉u.otp = malloc( sizeof(char) * 255);␊ |
| ␉␉strcpy(u.otp, row[1]);␊ |
| ␉}␊ |
| ␊ |
| ␉mysql_free_result(result);␊ |
| ␉mysql_close(con);␊ |
|
| ␊ |
| // future␊ |
| // linger 300␊ |
| DB * readConfig(char * config_path)␊ |
| DB readConfig(char * config_path)␊ |
| {␊ |
| ␉FILE *ifp;␊ |
| ␉DB * d;␊ |
| ␉DB d;␊ |
| ␉char config[255];␊ |
| ␉char value[255];␊ |
| ␉ifp = fopen(config_path, "r");␊ |
|
| ␉␉{␊ |
| ␉␉␉if (strcmp(value, "mysql") == 0)␊ |
| ␉␉␉{␊ |
| ␉␉␉␉d->type = MYSQLDB;␊ |
| ␉␉␉␉d.type = MYSQLDB;␊ |
| ␉␉␉}␊ |
| ␉␉␉continue;␊ |
| ␉␉}␊ |
| ␊ |
| ␉␉if (strcmp(config, "dbhost") == 0)␊ |
| ␉␉{␊ |
| ␉␉␉strcpy(d->dbhost, value);␊ |
| ␉␉␉strcpy(d.dbhost, value);␊ |
| ␉␉␉continue;␊ |
| ␉␉}␊ |
| ␊ |
| ␉␉if (strcmp(config, "dbport") == 0)␊ |
| ␉␉{␊ |
| ␉␉␉sprintf(value, "%d", &d->dbport);␊ |
| ␉␉␉sprintf(value, "%d", &d.dbport);␊ |
| ␉␉␉continue;␊ |
| ␉␉}␊ |
| ␊ |
| ␉␉if (strcmp(config, "dbuser") == 0)␊ |
| ␉␉{␊ |
| ␉␉␉strcpy(d->dbuser, value);␊ |
| ␉␉␉strcpy(d.dbuser, value);␊ |
| ␉␉␉continue;␊ |
| ␉␉}␊ |
| ␊ |
| ␉␉if (strcmp(config, "dbpass") == 0)␊ |
| ␉␉{␊ |
| ␉␉␉strcpy(d->dbpass, value);␊ |
| ␉␉␉strcpy(d.dbpass, value);␊ |
| ␉␉␉continue;␊ |
| ␉␉}␊ |
| ␊ |
| ␉␉if (strcmp(config, "dbtable") == 0)␊ |
| ␉␉{␊ |
| ␉␉␉strcpy(d->dbtable, value);␊ |
| ␉␉␉strcpy(d.dbtable, value);␊ |
| ␉␉␉continue;␊ |
| ␉␉}␊ |
| ␊ |
| ␉␉if (strcmp(config, "dbname") == 0)␊ |
| ␉␉{␊ |
| ␉␉␉strcpy(d->dbname, value);␊ |
| ␉␉␉strcpy(d.dbname, value);␊ |
| ␉␉␉continue;␊ |
| ␉␉}␊ |
| ␊ |
| ␉␉if (strcmp(config, "dbpassfield") == 0)␊ |
| ␉␉{␊ |
| ␉␉␉strcpy(d->passfield, value);␊ |
| ␉␉␉strcpy(d.passfield, value);␊ |
| ␉␉␉continue;␊ |
| ␉␉}␊ |
| ␊ |
| ␉␉if (strcmp(config, "dbotpfield") == 0)␊ |
| ␉␉{␊ |
| ␉␉␉strcpy(d->otpfield, value);␊ |
| ␉␉␉strcpy(d.otpfield, value);␊ |
| ␉␉␉continue;␊ |
| ␉␉}␊ |
| ␉}␊ |
| ␉return d;␊ |
| }␊ |
| ␊ |
| void freemem(User u)␊ |
| {␊ |
| ␉if (u.password != NULL)␊ |
| ␉␉free(u.password);␊ |
| ␉if (u.otp != NULL)␊ |
| ␉␉free(u.otp);␊ |
| }␊ |
| ␊ |
| int authotp(char * user_name, char * user_passwd) //, char * config_path)␊ |
| {␊ |
| ␉DB * db;␊ |
| ␉User * user;␊ |
| ␉DB db;␊ |
| ␉User user;␊ |
| ␉unsigned char outHash[20];␊ |
| ␉char * ret;␊ |
| ␉char * ret2;␊ |
|
| ␉//db = readConfig(getenv("OTPCONFIG"));␊ |
| ␉db = readConfig("/etc/apache2/configotp");␊ |
| ␉user = getMySQLUser(user_name, db);␊ |
| ␉if (user == NULL)␊ |
| ␉if (user.user == NULL)␊ |
| ␉{␊ |
| ␉␉free(db);␊ |
| ␉␉//free(db);␊ |
| ␉␉freemem(user);␊ |
| exit(1);␊ |
| ␉}␊ |
| ␉␊ |
| ␉// if user does not have a OTP set - just verify password␊ |
| ␉if (user->otp == NULL) ␊ |
| ␉if (user.otp == NULL) ␊ |
| ␉{␊ |
| ␉␉hash("SHA1", user_passwd, strlen(user_passwd), outHash);␊ |
| ␉␉ret = b64encode(outHash, 20);␊ |
| ␉␉if (strcmp(ret, user->password) == 0)␊ |
| ␉␉if (strcmp(ret, user.password) == 0)␊ |
| ␉␉␉retcode = 0;␊ |
| ␉␉else␊ |
| ␉␉␉retcode = 1;␊ |
| ␉␉free(db);␊ |
| free(user);␊ |
| ␉␉//free(db);␊ |
| //free(user);␊ |
| ␉␉freemem(user);␊ |
| ␉␉exit(retcode);␊ |
| ␉} else {␊ |
| ␉␉// password should be in the form {OTP}{PASSWORD}␊ |
|
| ␉␉if (strlen(user_passwd) < 7) // 6 OTP digits and 1 char for password␊ |
| ␉␉{␊ |
| ␉␉␉printf("password not long enough!");␊ |
| ␉␉␉free(db);␊ |
| ␉␉␉free(user);␊ |
| ␉␉␉//free(db);␊ |
| ␉␉␉//free(user);␊ |
| ␉␉␉freemem(user);␊ |
| ␉␉␉exit(1);␊ |
| ␉␉}␊ |
| ␉␉for(keylen = 0; keylen < sizeof(newkey) && user->otp[ik] != '\0'; keylen++)␊ |
| ␉␉for(keylen = 0; keylen < sizeof(newkey) && user.otp[ik] != '\0'; keylen++)␊ |
| ␉␉{␊ |
| ␉␉␉for(i = 0; i < 2; i++)␊ |
| ␉␉␉{␊ |
| ␉␉␉␉if (isdigit(user->otp[ik]))␊ |
| ␉␉␉␉␉nibs[i] = user->otp[ik] - '0';␊ |
| ␉␉␉␉else if (isxdigit(user->otp[ik]))␊ |
| ␉␉␉␉␉nibs[i] = tolower(user->otp[ik]) - 'a' + 10;␊ |
| ␉␉␉␉if (isdigit(user.otp[ik]))␊ |
| ␉␉␉␉␉nibs[i] = user.otp[ik] - '0';␊ |
| ␉␉␉␉else if (isxdigit(user.otp[ik]))␊ |
| ␉␉␉␉␉nibs[i] = tolower(user.otp[ik]) - 'a' + 10;␊ |
| ␉␉␉␉ik++;␊ |
| ␉␉␉}␊ |
| ␉␉␉newkey[keylen] = (nibs[0] << 4) | nibs[1];␊ |
|
| ␉␉strcpy(password, user_passwd + 6);␊ |
| ␉␉hash("SHA1", password, strlen(password), outHash);␊ |
| ␉␉ret2 = b64encode(outHash, 20);␊ |
| ␉␉if (strcmp(ret2, user->password) == 0 && strcmp(buf10, inotp) == 0)␊ |
| ␉␉if (strcmp(ret2, user.password) == 0 && strcmp(buf10, inotp) == 0)␊ |
| ␉␉{␊ |
| ␉␉␉free(user);␊ |
| ␉␉␉free(db);␊ |
| ␉␉␉//free(user);␊ |
| ␉␉␉//free(db);␊ |
| ␉␉␉freemem(user);␊ |
| ␉␉␉exit(0);␊ |
| ␉␉} else {␊ |
| ␉␉␉free(user);␊ |
| ␉␉␉free(db);␊ |
| ␉␉␉//free(user);␊ |
| ␉␉␉//free(db);␊ |
| ␉␉␉freemem(user);␊ |
| ␉␉␉exit(1);␊ |
| ␉␉}␊ |
| ␉}␊ |
| ␊ |
| ␉free(user);␊ |
| ␉free(db);␊ |
| ␉//free(user);␊ |
| ␉//free(db);␊ |
| ␉freemem(user);␊ |
| ␉return 0;␊ |
| }␊ |
| ␊ |