Merge commit from fork

For your consideration
This commit is contained in:
Nate Bargmann 2026-06-12 08:59:45 -05:00 committed by GitHub
commit 55366e14f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 117 additions and 36 deletions

View file

@ -2766,7 +2766,11 @@ int netrigctl_password(RIG *rig, const char *key1)
SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\password %s\n", key1);
retval = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf);
if (retval != RIG_OK) { retval = -RIG_EPROTO; }
if (retval != RIG_OK)
{
//rig_debug(RIG_DEBUG_ERR, "%s; retval = %d\n", __func__, retval);
retval = -RIG_EPROTO;
}
RETURNFUNC(retval);
}

View file

@ -56,6 +56,7 @@ HAMLIB_EXPORT(void) rig_password_generate_secret(char *pass,
const char *md5str = rig_make_md5(newpass);
strncpy(result, md5str, HAMLIB_SECRET_LENGTH);
result[HAMLIB_SECRET_LENGTH] = '\0';
// now that we have the md5 we'll do the AES256

View file

@ -1475,9 +1475,6 @@ shortcut:
return -RIG_EIO;
}
// check to see if our string starts with \...if so we need more chars
if (total_count == 0 && rxbuffer[total_count] == '\\') { rxmax = (rxmax - 1) * 5; }
total_count += (int) rd_count;
if (total_count == rxmax) { break; }

View file

@ -792,6 +792,7 @@ int main(int argc, char *argv[])
#endif
elapsed_ms(&powerstat_check_time, HAMLIB_ELAPSED_SET);
rigctl_parse_init(); // Not really needed here (yet)
do
{

View file

@ -104,12 +104,10 @@ extern int read_history();
static int chk_vfo_executed;
char rigctld_password[65];
int is_passwordOK;
int is_rigctld;
extern int lock_mode; // used by rigctld
extern powerstat_t rig_powerstat;
pthread_key_t thread_data_key;
/* variables for readline support */
@ -258,8 +256,10 @@ declare_proto_rig(set_cache);
declare_proto_rig(get_cache);
declare_proto_rig(halt);
declare_proto_rig(pause);
#if RIGCTLD_PASSWORDS
declare_proto_rig(password);
//declare_proto_rig(set_password);
#endif
declare_proto_rig(set_clock);
declare_proto_rig(get_clock);
declare_proto_rig(set_separator);
@ -376,8 +376,10 @@ static struct test_table test_list[] =
{ 0xf8, "set_clock", ACTION(set_clock), ARG_IN | ARG_NOVFO, "local or utc or YYYY-MM-DDTHH:MM:SS.sss+ZZ or YYYY-MM-DDTHH:MM+ZZ" },
{ 0xf1, "halt", ACTION(halt), ARG_NOVFO }, /* rigctld only--halt the daemon */
{ 0x8c, "pause", ACTION(pause), ARG_IN | ARG_NOVFO, "Seconds" },
#if RIGCTLD_PASSWORDS
{ 0x98, "password", ACTION(password), ARG_IN | ARG_NOVFO, "Password" },
// { 0x99, "set_password", ACTION(set_password), ARG_IN | ARG_NOVFO, "Password" },
#endif
{ 0xa0, "set_separator", ACTION(set_separator), ARG_IN | ARG_NOVFO, "Separator" },
{ 0xa1, "get_separator", ACTION(get_separator), ARG_NOVFO, "Separator" },
{ 0xa2, "set_lock_mode", ACTION(set_lock_mode), ARG_IN | ARG_NOVFO, "Locked" },
@ -700,6 +702,19 @@ static int next_word(char *buffer, int argc, char *argv[], int newline)
})
void rigctl_parse_init(/* int threaded */)
{
int retval;
retval = pthread_key_create(&thread_data_key, NULL);
if (retval != 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: Thread data key not created\n", __func__);
}
return;
}
int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
sync_cb_t sync_cb,
int interactive, int prompt, int *vfo_opt, char send_cmd_term,
@ -709,6 +724,7 @@ int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc,
unsigned char cmd;
struct test_table *cmd_entry = NULL;
struct rig_state *rs = STATE(my_rig);
struct handle_data *connection;
char command[MAXARGSZ + 1] = "";
char arg1[MAXARGSZ + 1], *p1 = NULL;
@ -1817,7 +1833,9 @@ readline_repeat:
else if (strcmp(cmd_entry->arg1, "Password") == 0) { preCmd = 1; }
}
if (use_password && !is_passwordOK && (cmd_entry->arg1 != NULL) && !preCmd)
connection = pthread_getspecific(thread_data_key); // Get state of this connection
if (use_password && !(connection ? connection->is_passwordOK : 0) && (cmd_entry->arg1 != NULL) && !preCmd)
{
rig_debug(RIG_DEBUG_ERR, "%s: password has not been provided\n", __func__);
fflush(fin);
@ -5533,21 +5551,33 @@ declare_proto_rig(pause)
return (RIG_OK);
}
int rigctld_password_check(RIG *rig, const char *md5)
#if RIGCTLD_PASSWORDS
// Compare our known secret with remote submission
// Returns 1 if match, 0 if not
static int rigctld_password_check(RIG *rig, const char *md5)
{
int retval = -RIG_EINVAL;
int retval;
int i, len, hits;
char padded[HAMLIB_SECRET_LENGTH + 1];
//fprintf(fout, "password %s\n", password);
//rig_debug(RIG_DEBUG_TRACE, "%s: %s == %s\n", __func__, md5, rigctld_password);
is_passwordOK = 0;
char *mymd5 = rig_make_md5(rigctld_password);
if (strcmp(md5, mymd5) == 0)
len = strlen(mymd5);
strncpy(padded, md5, HAMLIB_SECRET_LENGTH);
padded[HAMLIB_SECRET_LENGTH] = '\0'; // Make sure it's a terminated string
/* Brute force, constant time comparison */
for (i = hits = 0; i <= len; i++)
{
retval = RIG_OK;
is_passwordOK = 1;
hits += (int)(padded[i] == mymd5[i]);
}
retval = (hits == len + 1); // Entire string + terminator
free(mymd5);
return (retval);
}
@ -5556,12 +5586,23 @@ declare_proto_rig(password)
{
int retval = -RIG_EPROTO;
const char *key = arg1;
struct handle_data *connection;
ENTERFUNC2;
if (is_rigctld)
{
retval = rigctld_password_check(rig, key);
connection = pthread_getspecific(thread_data_key);
if (connection)
{
connection->is_passwordOK = retval;
retval = retval == 1 ? RIG_OK : -RIG_EPROTO;
}
else
{
retval = -RIG_EPROTO;
}
}
else
{
@ -5583,6 +5624,7 @@ declare_proto_rig(password)
RETURNFUNC2(retval);
}
#endif
#if 0 // don't think we need this yet
/* 0x99 */

View file

@ -26,11 +26,36 @@
#define RIGCTL_PARSE_H
#include <stdio.h>
#include <pthread.h>
#include "hamlib/rig.h"
#define RIGCTL_PARSE_END 1
#define RIGCTL_PARSE_ERROR 2
/*
* Temporary disable of rigctld/rigctltcp passwords and their help text, so no expctations
* of them working
* Set this to 1 when they are repaired
*/
#define RIGCTLD_PASSWORDS 1
/* Data that ties each thread to a connection
* Serves as the initial thread data, then as the state info for individual
* connections
*/
struct handle_data
{
RIG *rig;
int sock;
struct sockaddr_storage cli_addr;
socklen_t clilen;
int vfo_mode;
int use_password;
int is_passwordOK;
};
extern pthread_key_t thread_data_key;
/*
* external prototype
*/
@ -51,6 +76,7 @@ int print_conf_list(const struct confparams *cfp, rig_ptr_t data);
int print_conf_list2(const struct confparams *cfp, rig_ptr_t data);
int set_conf(RIG *my_rig, char *conf_parms);
void rigctl_parse_init(void);
typedef void (*sync_cb_t)(int);
int rigctl_parse(RIG *my_rig, FILE *fin, FILE *fout, char *argv[], int argc, sync_cb_t sync_cb,
int interactive, int prompt, int * vfo_mode, char send_cmd_term,

View file

@ -107,24 +107,15 @@ static struct option long_options[] =
{"twiddle_rit", 1, 0, 'w'},
{"uplink", 1, 0, 'x'},
{"debug-time-stamps", 0, 0, 'Z'},
#if RIGCTLD_PASSWORDS
{"password", 1, 0, 'A'},
#endif
{"rigctld-idle", 0, 0, 'R'},
{"bind-all", 0, 0, 'b'},
{0, 0, 0, 0}
};
struct handle_data
{
RIG *rig;
int sock;
struct sockaddr_storage cli_addr;
socklen_t clilen;
int vfo_mode;
int use_password;
};
/*
* Prototypes
*/
@ -320,6 +311,7 @@ int main(int argc, char *argv[])
bind_all = 1;
break;
#if RIGCTLD_PASSWORDS
case 'A':
strncpy(rigctld_password, optarg, sizeof(rigctld_password) - 1);
//char *md5 = rig_make_m d5(rigctld_password);
@ -328,6 +320,7 @@ int main(int argc, char *argv[])
printf("Secret key: %s\n", md5);
rig_settings_save("sharedkey", md5, e_CHAR);
break;
#endif
case 'm':
my_model = atoi(optarg);
@ -971,6 +964,8 @@ int main(int argc, char *argv[])
#endif
#endif
rigctl_parse_init();
/*
* main loop accepting connections
*/
@ -1170,6 +1165,13 @@ void *handle_socket(void *arg)
goto handle_exit;
}
retcode = pthread_setspecific(thread_data_key, arg);
if (0 != retcode)
{
rig_debug(RIG_DEBUG_ERR, "%s: Could not set thread daya\n", __func__);
// What do we do here?
}
mutex_rigctld(1);
++client_count;
@ -1357,6 +1359,7 @@ handle_exit:
#endif
pthread_setspecific(thread_data_key, NULL); // Tell pthreads we're done with the data
free(arg);
pthread_exit(NULL);
@ -1392,7 +1395,9 @@ static void usage(FILE *fout)
" -w, --twiddle_rit=SECONDS suppress VFOB getfreq so RIT can be twiddled\n"
" -x, --uplink=OPTION set uplink get_freq ignore, option 1=Sub, 2=Main\n"
" -Z, --debug-time-stamps enable time stamps for debug messages\n"
#if RIGCTLD_PASSWORDS
" -A, --password=PASSWORD set password for rigctld access (NOT IMPLEMENTED)\n"
#endif
" -R, --rigctld-idle make rigctld close the rig when no clients are connected\n"
" -b, --bind-all make rigctld bind to first network device available\n"
" -h, --help display this help and exit\n"

View file

@ -112,23 +112,14 @@ static struct option long_options[] =
{"debug-time-stamps", 0, 0, 'Z'},
{"multicast-addr", 1, 0, 'M'},
{"multicast-port", 1, 0, 'n'},
#if RIGCTLD_PASSWORDS
{"password", 1, 0, 'A'},
#endif
{"rigctld-idle", 0, 0, 'R'},
{0, 0, 0, 0}
};
struct handle_data
{
RIG *rig;
int sock;
struct sockaddr_storage cli_addr;
socklen_t clilen;
int vfo_mode;
int use_password;
};
void *handle_socket(void *arg);
static void usage(FILE *fout);
@ -313,6 +304,7 @@ int main(int argc, char *argv[])
rigctld_idle = 1;
break;
#if RIIGCTLD_PASSWORDS
case 'A':
strncpy(rigctld_password, optarg, sizeof(rigctld_password) - 1);
//char *md5 = rig_make_m d5(rigctld_password);
@ -321,6 +313,7 @@ int main(int argc, char *argv[])
printf("Secret key: %s\n", md5);
rig_settings_save("sharedkey", md5, e_CHAR);
break;
#endif
case 'm':
my_model = atoi(optarg);
@ -876,6 +869,8 @@ int main(int argc, char *argv[])
#endif
#endif
rigctl_parse_init();
/*
* main loop accepting connections
*/
@ -1068,6 +1063,13 @@ void *handle_socket(void *arg)
goto handle_exit;
}
retcode = pthread_setspecific(thread_data_key, arg);
if (retcode != 0)
{
rig_debug(RIG_DEBUG_ERR, "%s: Could not set thread data\n", __func__);
// What should we do here???
}
mutex_rigctld(1);
++client_count;
@ -1354,6 +1356,7 @@ handle_exit:
#endif
pthread_setspecific(thread_data_key, NULL);
free(arg);
pthread_exit(NULL);
@ -1390,7 +1393,9 @@ static void usage(FILE *fout)
" -w, --twiddle_rit=SECONDS suppress VFOB getfreq so RIT can be twiddled\n"
" -x, --uplink=OPTION set uplink get_freq ignore, option 1=Sub, 2=Main\n"
" -Z, --debug-time-stamps enable time stamps for debug messages\n"
#if RIGCTLD_PASSWORDS
" -A, --password=PASSWORD set password for rigctld access (64 chars max), default none\n"
#endif
" -R, --rigctltcp-idle make rigctltcp close the rig when no clients are connected\n"
" -h, --help display this help and exit\n"
" -V, --version output version information and exit\n\n",