From b4002b2357c1e266410169bf4221abe4879b8491 Mon Sep 17 00:00:00 2001 From: Fred Gleason <fredg@paravelsystems.com> Date: Fri, 6 Nov 2020 16:42:10 -0500 Subject: [PATCH] 2020-11-06 Fred Gleason <fredg@paravelsystems.com> * Consolidated ticket processing operations in new 'RDUser::createTicket()' and 'RDUser::ticketIsValid()' methods. Signed-off-by: Fred Gleason <fredg@paravelsystems.com> --- ChangeLog | 3 ++ lib/rdformpost.cpp | 13 ++----- lib/rduser.cpp | 80 +++++++++++++++++++++++++++++++++++++++++ lib/rduser.h | 6 ++++ web/rdxport/rdxport.cpp | 58 +++++++++--------------------- 5 files changed, 108 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index e047481e..741088d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20544,3 +20544,6 @@ 2020-11-06 Fred Gleason <fredg@paravelsystems.com> * Fixed a bug in Webget that caused authentication to fail when using PAM. +2020-11-06 Fred Gleason <fredg@paravelsystems.com> + * Consolidated ticket processing operations in new + 'RDUser::createTicket()' and 'RDUser::ticketIsValid()' methods. diff --git a/lib/rdformpost.cpp b/lib/rdformpost.cpp index a956858b..a3829f75 100644 --- a/lib/rdformpost.cpp +++ b/lib/rdformpost.cpp @@ -323,7 +323,7 @@ bool RDFormPost::authenticate(bool *used_ticket) { QString ticket; QString sql; - RDSqlQuery *q; + RDSqlQuery *q=NULL; QString name; QString passwd; @@ -334,20 +334,13 @@ bool RDFormPost::authenticate(bool *used_ticket) *used_ticket=false; } if(getValue("TICKET",&ticket)) { - sql=QString("select LOGIN_NAME from WEBAPI_AUTHS where ")+ - "(TICKET=\""+RDEscapeString(ticket)+"\")&&"+ - "(IPV4_ADDRESS=\""+clientAddress().toString()+"\")&&"+ - "(EXPIRATION_DATETIME>now())"; - q=new RDSqlQuery(sql); - if(q->first()) { - rda->user()->setName(q->value(0).toString()); - delete q; + if(RDUser::ticketIsValid(ticket,clientAddress(),&name)) { + rda->user()->setName(name); if(used_ticket!=NULL) { *used_ticket=true; } return true; } - delete q; } // diff --git a/lib/rduser.cpp b/lib/rduser.cpp index cc87f977..ae7d8528 100644 --- a/lib/rduser.cpp +++ b/lib/rduser.cpp @@ -19,6 +19,9 @@ // #include <stdlib.h> +#include <sys/time.h> + +#include <openssl/sha.h> #include <rdconf.h> #include <rdpam.h> @@ -607,6 +610,83 @@ QStringList RDUser::services() const } +bool RDUser::createTicket(QString *ticket,QDateTime *expire_dt, + const QHostAddress &client_addr, + const QDateTime &start_dt) const +{ + *ticket=QString(); + *expire_dt=QDateTime(); + + if(exists()) { + char rawstr[1024]; + unsigned char sha1[SHA_DIGEST_LENGTH]; + QString sql; + struct timeval tv; + + memset(&tv,0,sizeof(tv)); + gettimeofday(&tv,NULL); + srandom(tv.tv_usec); + for(int i=0;i<5;i++) { + long r=random(); + unsigned ipv4_addr=client_addr.toIPv4Address(); + snprintf(rawstr+i*8,8,"%c%c%c%c%c%c%c%c", + 0xff&((int)r>>24),0xff&(ipv4_addr>>24), + 0xff&((int)r>>16),0xff&(ipv4_addr>>16), + 0xff&((int)r>>8),0xff&(ipv4_addr>>8), + 0xff&(int)r,0xff&ipv4_addr); + } + SHA1((const unsigned char *)rawstr,40,sha1); + *ticket=""; + for(int i=0;i<SHA_DIGEST_LENGTH;i++) { + *ticket+=QString().sprintf("%02x",0xFF&rawstr[i]); + } + *expire_dt=start_dt.addSecs(webapiAuthTimeout()); + sql=QString("insert into WEBAPI_AUTHS set ")+ + "TICKET=\""+RDEscapeString(*ticket)+"\","+ + "LOGIN_NAME=\""+RDEscapeString(name())+"\","+ + "IPV4_ADDRESS=\""+client_addr.toString()+"\","+ + "EXPIRATION_DATETIME=\""+ + expire_dt->toString("yyyy-MM-dd hh:mm:ss")+"\""; + RDSqlQuery::apply(sql); + + return true; + } + + return false; +} + + +bool RDUser::ticketIsValid(const QString &ticket, + const QHostAddress &client_addr, + QString *username,QDateTime *expire_dt) +{ + QString sql; + RDSqlQuery *q=NULL; + + sql=QString("select ")+ + "LOGIN_NAME,"+ // 00 + "EXPIRATION_DATETIME "+ // 01 + "from WEBAPI_AUTHS where "+ + "(TICKET=\""+RDEscapeString(ticket)+"\")&&"+ + "(IPV4_ADDRESS=\""+client_addr.toString()+"\")&&"+ + "(EXPIRATION_DATETIME>now())"; + q=new RDSqlQuery(sql); + if(q->first()) { + if(username!=NULL) { + *username=q->value(0).toString(); + } + if(expire_dt!=NULL) { + *expire_dt=q->value(1).toDateTime(); + } + delete q; + return true; + } + delete q; + + return false; +} + + bool RDUser::emailIsValid(const QString &addr) { QStringList f0=addr.split("@",QString::KeepEmptyParts); diff --git a/lib/rduser.h b/lib/rduser.h index 99d95c92..a17d6072 100644 --- a/lib/rduser.h +++ b/lib/rduser.h @@ -96,6 +96,12 @@ class RDUser bool feedAuthorized(const QString &keyname); QString serviceCheckDefault(QString serv) const; QStringList services() const; + bool createTicket(QString *ticket,QDateTime *expire_dt, + const QHostAddress &client_addr, + const QDateTime &start_dt) const; + static bool ticketIsValid(const QString &ticket, + const QHostAddress &client_addr, + QString *username=NULL,QDateTime *expire_dt=NULL); static bool emailIsValid(const QString &addr); static QString emailContact(const QString &addr,const QString &fullname); diff --git a/web/rdxport/rdxport.cpp b/web/rdxport/rdxport.cpp index e4b35cab..d4a07e25 100644 --- a/web/rdxport/rdxport.cpp +++ b/web/rdxport/rdxport.cpp @@ -23,7 +23,6 @@ #include <stdlib.h> #include <stdio.h> #include <syslog.h> -#include <openssl/sha.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> @@ -402,52 +401,27 @@ bool Xport::Authenticate() void Xport::TryCreateTicket(const QString &name) { - QString ticket; - QString passwd; int command; - char rawstr[1024]; - unsigned char sha1[SHA_DIGEST_LENGTH]; - QString sql; - RDSqlQuery *q; if(xport_post->getValue("COMMAND",&command)) { if(command==RDXPORT_COMMAND_CREATETICKET) { - struct timeval tv; - memset(&tv,0,sizeof(tv)); - gettimeofday(&tv,NULL); - srandom(tv.tv_usec); - for(int i=0;i<5;i++) { - long r=random(); - unsigned ipv4_addr=xport_post->clientAddress().toIPv4Address(); - snprintf(rawstr+i*8,8,"%c%c%c%c%c%c%c%c", - 0xff&((int)r>>24),0xff&(ipv4_addr>>24), - 0xff&((int)r>>16),0xff&(ipv4_addr>>16), - 0xff&((int)r>>8),0xff&(ipv4_addr>>8), - 0xff&(int)r,0xff&ipv4_addr); - } - SHA1((const unsigned char *)rawstr,40,sha1); - ticket=""; - for(int i=0;i<SHA_DIGEST_LENGTH;i++) { - ticket+=QString().sprintf("%02x",0xFF&rawstr[i]); - } QDateTime now=QDateTime::currentDateTime(); - sql=QString("insert into WEBAPI_AUTHS set ")+ - "TICKET=\""+RDEscapeString(ticket)+"\","+ - "LOGIN_NAME=\""+RDEscapeString(name)+"\","+ - "IPV4_ADDRESS=\""+xport_post->clientAddress().toString()+"\","+ - "EXPIRATION_DATETIME=\""+ - now.addSecs(rda->user()->webapiAuthTimeout()). - toString("yyyy-MM-dd hh:mm:ss")+"\""; - q=new RDSqlQuery(sql); - delete q; - printf("Content-type: application/xml\n\n"); - printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); - printf("<ticketInfo>\n"); - printf(" %s\n",(const char *)RDXmlField("ticket",ticket).utf8()); - printf(" %s\n",(const char *) - RDXmlField("expires",now.addSecs(rda->user()->webapiAuthTimeout())).utf8()); - printf("</ticketInfo>\n"); - exit(0); + QString ticket; + QDateTime expire_datetime; + if(rda->user()->createTicket(&ticket,&expire_datetime, + xport_post->clientAddress(),now)) { + printf("Content-type: application/xml\n\n"); + printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); + printf("<ticketInfo>\n"); + printf(" %s\n",RDXmlField("ticket",ticket).utf8().constData()); + printf(" %s\n", + (const char *)RDXmlField("expires",expire_datetime).utf8()); + printf("</ticketInfo>\n"); + exit(0); + } + else { + XmlExit("Ticket creation failed",500,"rdxport.cpp",LINE_NUMBER); + } } } }