1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
/*
* VeyonAuthHelper.cpp - main file for Veyon Authentication Helper
*
* Copyright (c) 2010-2022 Tobias Junghans <tobydox@veyon.io>
*
* This file is part of Veyon - https://veyon.io
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include <QDataStream>
#include <QFile>
#include <security/pam_appl.h>
static QByteArray pam_username; // clazy:exclude=non-pod-global-static
static QByteArray pam_password; // clazy:exclude=non-pod-global-static
static QByteArray pam_service; // clazy:exclude=non-pod-global-static
static int pam_conv( int num_msg, const struct pam_message** msg, struct pam_response** resp, void * )
{
auto reply = reinterpret_cast<pam_response *>(
malloc( sizeof(struct pam_response) * static_cast<size_t>( num_msg ) ) );
if( reply == nullptr )
{
return PAM_CONV_ERR;
}
for( int replies = 0; replies < num_msg; ++replies )
{
switch( msg[replies]->msg_style )
{
case PAM_PROMPT_ECHO_ON:
reply[replies].resp_retcode = PAM_SUCCESS;
reply[replies].resp = strdup( pam_username.constData() );
break;
case PAM_PROMPT_ECHO_OFF:
reply[replies].resp_retcode = PAM_SUCCESS;
reply[replies].resp = strdup( pam_password.constData() );
break;
case PAM_TEXT_INFO:
case PAM_ERROR_MSG:
reply[replies].resp_retcode = PAM_SUCCESS;
reply[replies].resp = nullptr;
break;
default:
free( reply );
return PAM_CONV_ERR;
}
}
*resp = reply;
return PAM_SUCCESS;
}
int main()
{
QFile stdIn;
stdIn.open( 0, QFile::ReadOnly | QFile::Unbuffered );
QDataStream ds( &stdIn );
ds >> pam_username;
ds >> pam_password;
ds >> pam_service;
if( pam_service.isEmpty() )
{
pam_service = QByteArrayLiteral("login");
}
struct pam_conv pconv = { &pam_conv, nullptr };
pam_handle_t* pamh = nullptr;
auto err = pam_start( pam_service.constData(), nullptr, &pconv, &pamh );
if( err == PAM_SUCCESS )
{
err = pam_authenticate( pamh, PAM_SILENT );
if( err != PAM_SUCCESS )
{
printf( "pam_authenticate: %s\n", pam_strerror( pamh, err ) );
}
else
{
err = pam_acct_mgmt( pamh, PAM_SILENT );
if( err != PAM_SUCCESS )
{
printf( "pam_acct_mgmt: %s\n", pam_strerror( pamh, err ) );
}
}
}
else
{
printf( "pam_start: %s\n", pam_strerror( pamh, err ) );
}
pam_end( pamh, err );
return err == PAM_SUCCESS ? 0 : -1;
}
|