2021-04-27 Fred Gleason <fredg@paravelsystems.com>

* Changed the 'RDAIRPLAY_EXIT_PASSWORD' field from 'varchar(41)'
	to 'varchar(48)'.
	* Incremented the database version to 349.
	* Renamed the 'RDSha1Hash()' function to 'RDSha1HashFile()'.
	* Added 'RDSha1HashPassword()' function in 'lib/rdhash.[cpp|h]'.
	* Added 'RDSha1HashCheckPassword()' function in 'lib/rdhash.[cpp|h]'.
	* Changed the hashing algorithm used for the Exit Password for
	rdairplay(1) to salted SHA1.

Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
Fred Gleason
2021-04-27 16:52:26 -04:00
parent 05c35a208c
commit 9a65658267
17 changed files with 164 additions and 46 deletions

View File

@@ -24,7 +24,7 @@
/*
* Current Database Version
*/
#define RD_VERSION_DATABASE 348
#define RD_VERSION_DATABASE 349
#endif // DBVERSION_H

View File

@@ -20,10 +20,11 @@
#include <QObject>
#include "rdairplay_conf.h"
#include "rddb.h"
#include "rdconf.h"
#include "rdairplay_conf.h"
#include "rdescape_string.h"
#include "rdhash.h"
RDAirPlayConf::RDAirPlayConf(const QString &station,const QString &tablename)
{
@@ -662,34 +663,40 @@ bool RDAirPlayConf::exitPasswordValid(const QString &passwd) const
{
QString sql;
RDSqlQuery *q;
sql=QString("select `EXIT_PASSWORD` from `")+air_tablename+"` where "+
"STATION='"+RDEscapeString(air_station)+"' && "+
"((`EXIT_PASSWORD`=PASSWORD('"+RDEscapeString(passwd)+"'))";
if(passwd.isEmpty()) {
sql+="||(`EXIT_PASSWORD` is null)";
}
sql+=")";
bool ret=false;
sql=QString("select ")+
"`EXIT_PASSWORD` "+ // 00
"from `"+air_tablename+"` where "+
"`STATION`='"+RDEscapeString(air_station)+"'";
q=new RDSqlQuery(sql);
if(q->size()>0) {
delete q;
return true;
if(q->first()) {
if(passwd.isEmpty()) {
ret=q->value(0).isNull();
}
else {
ret=RDSha1HashCheckPassword(passwd,q->value(0).toString());
}
}
delete q;
return false;
return ret;
}
void RDAirPlayConf::setExitPassword(const QString &passwd) const
{
QString sql;
RDSqlQuery *q;
sql=QString("update `")+air_tablename+"` set "+
"`EXIT_PASSWORD`=PASSWORD('"+RDEscapeString(passwd)+"') where "+
"`STATION`='"+RDEscapeString(air_station)+"'";
q=new RDSqlQuery(sql);
delete q;
if(passwd.isEmpty()) {
sql=QString("update `")+air_tablename+"` set "+
"`EXIT_PASSWORD`=null where "+
"`STATION`='"+RDEscapeString(air_station)+"'";
}
else {
sql=QString("update `")+air_tablename+"` set "+
"`EXIT_PASSWORD`='"+RDEscapeString(RDSha1HashPassword(passwd))+"' where "+
"`STATION`='"+RDEscapeString(air_station)+"'";
}
RDSqlQuery::apply(sql);
}

View File

@@ -27,9 +27,28 @@
#include <openssl/sha.h>
#include <QDateTime>
#include "rdhash.h"
QString RDSha1Hash(const QString &filename,bool throttle)
QString __RDSha1Hash_MakePasswordHash(const QString &secret,const QString &salt)
{
SHA_CTX ctx;
unsigned char md[SHA_DIGEST_LENGTH];
SHA1_Init(&ctx);
SHA1_Update(&ctx,salt.toUtf8(),salt.toUtf8().length());
SHA1_Update(&ctx,secret.toUtf8(),secret.toUtf8().length());
SHA1_Final(md,&ctx);
QString ret=salt;
for(int i=0;i<SHA_DIGEST_LENGTH;i++) {
ret+=QString().sprintf("%02x",0xff&md[i]);
}
return ret;
}
QString RDSha1HashFile(const QString &filename,bool throttle)
{
QString ret;
SHA_CTX ctx;
@@ -57,3 +76,27 @@ QString RDSha1Hash(const QString &filename,bool throttle)
return ret;
}
QString RDSha1HashPassword(const QString &secret)
{
//
// Create a salt value
//
srand(QDateTime::currentDateTime().toMSecsSinceEpoch());
QString salt=QString().sprintf("%08x",rand());
//
// Generate the hash
//
return __RDSha1Hash_MakePasswordHash(secret,salt);
}
bool RDSha1HashCheckPassword(const QString &secret,const QString &hash)
{
QString salt=secret.left(8);
return __RDSha1Hash_MakePasswordHash(secret,hash.left(8))==hash;
}

View File

@@ -23,7 +23,9 @@
#include <qstring.h>
QString RDSha1Hash(const QString &filename,bool throttle=false);
QString RDSha1HashFile(const QString &filename,bool throttle=false);
QString RDSha1HashPassword(const QString &secret);
bool RDSha1HashCheckPassword(const QString &secret,const QString &hash);
#endif // RD_H
#endif // RDHASH_H