2020-11-06 Fred Gleason <fredg@paravelsystems.com>

* Modified Webget to use tickets for authenticating media transfer
	requests.

Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
Fred Gleason 2020-11-06 18:34:53 -05:00
parent b4002b2357
commit 0385548139
6 changed files with 59 additions and 19 deletions

View File

@ -20547,3 +20547,6 @@
2020-11-06 Fred Gleason <fredg@paravelsystems.com>
* Consolidated ticket processing operations in new
'RDUser::createTicket()' and 'RDUser::ticketIsValid()' methods.
2020-11-06 Fred Gleason <fredg@paravelsystems.com>
* Modified Webget to use tickets for authenticating media transfer
requests.

View File

@ -612,10 +612,13 @@ QStringList RDUser::services() const
bool RDUser::createTicket(QString *ticket,QDateTime *expire_dt,
const QHostAddress &client_addr,
const QDateTime &start_dt) const
QDateTime start_dt) const
{
*ticket=QString();
*expire_dt=QDateTime();
if(!start_dt.isValid()) {
start_dt=QDateTime::currentDateTime();
}
if(exists()) {
char rawstr[1024];

View File

@ -2,7 +2,7 @@
//
// Abstract a Rivendell User
//
// (C) Copyright 2002-2004,2016 Fred Gleason <fredg@paravelsystems.com>
// (C) Copyright 2002-2020 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -21,6 +21,8 @@
#ifndef RDUSER_H
#define RDUSER_H
#include <QDateTime>
class RDUser
{
public:
@ -98,7 +100,7 @@ class RDUser
QStringList services() const;
bool createTicket(QString *ticket,QDateTime *expire_dt,
const QHostAddress &client_addr,
const QDateTime &start_dt) const;
QDateTime start_dt=QDateTime()) const;
static bool ticketIsValid(const QString &ticket,
const QHostAddress &client_addr,
QString *username=NULL,QDateTime *expire_dt=NULL);

View File

@ -82,7 +82,7 @@ MainObject::MainObject(QObject *parent)
TextExit("missing REQUEST_METHOD",500,LINE_NUMBER);
}
if(QString(getenv("REQUEST_METHOD")).lower()=="get") {
ServeLogin();
ServeLogin(200);
Exit(0);
}
if(QString(getenv("REQUEST_METHOD")).lower()!="post") {
@ -118,7 +118,7 @@ MainObject::MainObject(QObject *parent)
// Authenticate Connection
//
if(!Authenticate()) {
ServeLogin();
ServeLogin(403);
Exit(0);
}
@ -156,7 +156,7 @@ void MainObject::ripcConnectedData(bool state)
direction.toUtf8().constData(),
webget_post->clientAddress().toString().toUtf8().constData());
rda->logAuthenticationFailure(webget_post->clientAddress()); // So Fail2Ban can notice this
ServeLogin();
ServeLogin(403);
}
@ -457,14 +457,11 @@ void MainObject::ServeForm()
printf(" <body>\n");
//
// Credentials
//
printf(" <input type=\"hidden\" name=\"LOGIN_NAME\" id=\"LOGIN_NAME\" value=\"%s\">\n",
rda->user()->name().toUtf8().constData());
printf(" <input type=\"hidden\" name=\"PASSWORD\" id=\"PASSWORD\" value=\"%s\">\n",
webget_remote_password.toUtf8().constData());
printf(" <input type=\"hidden\" name=\"TICKET\" id=\"TICKET\" value=\"%s\">\n",
webget_ticket.toUtf8().constData());
//
// Get Audio
@ -554,9 +551,11 @@ void MainObject::ServeForm()
}
void MainObject::ServeLogin()
void MainObject::ServeLogin(int resp_code)
{
printf("Content-type: text/html\n\n");
printf("Content-type: text/html\n");
printf("Status: %d\n",resp_code);
printf("\n");
//
// Head
@ -601,6 +600,27 @@ void MainObject::ServeLogin()
bool MainObject::Authenticate()
{
QDateTime expire_dt;
//
// First try ticket authentication
//
if(webget_post->getValue("TICKET",&webget_ticket)) {
if(RDUser::ticketIsValid(webget_ticket,webget_post->clientAddress(),
&webget_remote_username)) {
rda->user()->setName(webget_remote_username);
if(!rda->user()->webgetLogin()) {
rda->logAuthenticationFailure(webget_post->clientAddress(),
webget_remote_username);
return false;
}
return true;
}
}
//
// Then, try to authenticate by username/password
//
if(!webget_post->getValue("LOGIN_NAME",&webget_remote_username)) {
rda->syslog(LOG_WARNING,"missing LOGIN_NAME");
rda->logAuthenticationFailure(webget_post->clientAddress());
@ -620,6 +640,12 @@ bool MainObject::Authenticate()
webget_remote_username);
return false;
}
if(!rda->user()->createTicket(&webget_ticket,&expire_dt,
webget_post->clientAddress())) {
rda->logAuthenticationFailure(webget_post->clientAddress(),
webget_remote_username);
return false;
}
return true;
}

View File

@ -44,7 +44,7 @@ class MainObject : public QObject
void GetAudio();
void PutAudio();
void ServeForm();
void ServeLogin();
void ServeLogin(int resp_code);
bool Authenticate();
void Exit(int code);
void TextExit(const QString &msg,int code,int line) const;
@ -52,6 +52,7 @@ class MainObject : public QObject
QString webget_remote_hostname;
QString webget_remote_username;
QString webget_remote_password;
QString webget_ticket;
QHostAddress webget_remote_address;
};

View File

@ -26,8 +26,7 @@ function ProcessGet()
{
form=new FormData();
form.append('LOGIN_NAME',Id('LOGIN_NAME').value);
form.append('PASSWORD',Id('PASSWORD').value);
form.append('TICKET',Id('TICKET').value);
form.append('direction','get');
form.append('title',Id('title').value);
form.append('preset',Id('preset').value);
@ -40,8 +39,7 @@ function ProcessPut()
{
form=new FormData();
form.append('LOGIN_NAME',Id('LOGIN_NAME').value);
form.append('PASSWORD',Id('PASSWORD').value);
form.append('TICKET',Id('TICKET').value);
form.append('direction','put');
form.append('group',Id('group').value);
form.append('filename',Id('filename').files[0]);
@ -77,7 +75,14 @@ function SendForm(form,url,spinner_id)
if(f0[0]=='text/html') {
reader=new FileReader();
reader.addEventListener('loadend',()=> {
alert(reader.result);
if(http.status==403) { // Ticket expired, display the login
document.open(http.getResponseHeader("Content-Type"));
document.write(reader.result);
document.close();
}
else {
alert(reader.result);
}
});
reader.readAsText(blob);
}