Stage 1 rigctld password working using MD5 hash

Need to add Stage 2 which will be encryption using the MD5 hash as the key so the secret key nevers gets trasmitted
Then need to add a "by connection" capability as password is permanent across connections right now.
pull/1022/head
Mike Black W9MDB 2022-04-15 13:21:35 -05:00
rodzic 3ac385ed05
commit 770aa4e98a
11 zmienionych plików z 473 dodań i 84 usunięć

Wyświetl plik

@ -1188,6 +1188,10 @@ Pause for the given whole (integer) number of
.RI \(aq Seconds \(aq .RI \(aq Seconds \(aq
before sending the next command to the radio. before sending the next command to the radio.
. .
.TP
.BR password " \(aq" \fIPassword\fP \(aq
Sends password to rigctld when rigctld has been secured with -A. Must use the 32-char shared secret from rigctld.
.
. .
.SH READLINE .SH READLINE
. .

Wyświetl plik

@ -359,7 +359,7 @@ option as it generates no output on its own.
. .
.TP .TP
.BR \-A ", " \-\-password .BR \-A ", " \-\-password
Sets password on rigcltd which requires hamlib to use rig_set_paswword and rigctl to use \\password to access rigctld Sets password on rigctld which requires hamlib to use rig_set_password and rigctl to use \\password to access rigctld. A 32-char shared secret will be displayed to be used on the client side.
. .
.TP .TP
.BR \-h ", " \-\-help .BR \-h ", " \-\-help

Wyświetl plik

@ -26,6 +26,9 @@
#define BUILTINFUNC 0 #define BUILTINFUNC 0
// Our shared secret password
#define HAMLIB_SECRET_LENGTH 32
#define TRACE rig_debug(RIG_DEBUG_TRACE,"%s(%d) trace\n", __FILE__, __LINE__) #define TRACE rig_debug(RIG_DEBUG_TRACE,"%s(%d) trace\n", __FILE__, __LINE__)
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
@ -2041,7 +2044,7 @@ struct rig_caps {
// this will be used to check rigcaps structure is compatible with client // this will be used to check rigcaps structure is compatible with client
char *hamlib_check_rig_caps; // a constant value we can check for hamlib integrity char *hamlib_check_rig_caps; // a constant value we can check for hamlib integrity
int (*get_conf2)(RIG *rig, token_t token, char *val, int val_len); int (*get_conf2)(RIG *rig, token_t token, char *val, int val_len);
int (*password)(RIG *rig, const unsigned char *key1, const unsigned char *key2); /*< Send encrypted password if rigctld is secured with -A/--password */ int (*password)(RIG *rig, const char *key1); /*< Send encrypted password if rigctld is secured with -A/--password */
}; };
//! @endcond //! @endcond
@ -3379,7 +3382,7 @@ extern HAMLIB_EXPORT(int) hl_usleep(rig_useconds_t msec);
extern HAMLIB_EXPORT(int) rig_cookie(RIG *rig, enum cookie_e cookie_cmd, char *cookie, int cookie_len); extern HAMLIB_EXPORT(int) rig_cookie(RIG *rig, enum cookie_e cookie_cmd, char *cookie, int cookie_len);
extern HAMLIB_EXPORT(int) rig_password(RIG *rig, const unsigned char *key1, const unsigned char *key2); extern HAMLIB_EXPORT(int) rig_password(RIG *rig, const char *key1);
//extern HAMLIB_EXPORT(int) //extern HAMLIB_EXPORT(int)
int longlat2locator HAMLIB_PARAMS((double longitude, int longlat2locator HAMLIB_PARAMS((double longitude,

Wyświetl plik

@ -2630,15 +2630,14 @@ static int netrigctl_power2mW(RIG *rig, unsigned int *mwpower, float power,
RETURNFUNC(RIG_OK); RETURNFUNC(RIG_OK);
} }
int netrigctl_password(RIG *rig, const unsigned char *key1, int netrigctl_password(RIG *rig, const char *key1)
const unsigned char *key2)
{ {
char cmdbuf[256]; char cmdbuf[256];
char buf[BUF_MAX]; char buf[BUF_MAX];
int retval; int retval;
ENTERFUNC; ENTERFUNC;
rig_debug(RIG_DEBUG_VERBOSE, "%s: key1=%s, key2=%s\n", __func__, key1, key2); rig_debug(RIG_DEBUG_VERBOSE, "%s: key1=%s\n", __func__, key1);
SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\password %s\n", key1); SNPRINTF(cmdbuf, sizeof(cmdbuf), "\\password %s\n", key1);
retval = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf); retval = netrigctl_transaction(rig, cmdbuf, strlen(cmdbuf), buf);
if (retval != RIG_OK) retval = -RIG_EPROTO; if (retval != RIG_OK) retval = -RIG_EPROTO;

Wyświetl plik

@ -1,7 +1,14 @@
EXTRA_DIST = sctest.c EXTRA_DIST = sctest.c
security_test_SOURCES = security_test.c aes.h AESStringCrypt.h password.h security.h sha256.h md5.c md5.h
security_test_LIBS = libsecurity.la
security_test_LDFLAGS = -L.
security_test_CFLAGS = -L. -I.
noinst_LTLIBRARIES = libsecurity.la noinst_LTLIBRARIES = libsecurity.la
libsecurity_la_SOURCES = aes.c AESStringCrypt.c password.c security.c sha256.c aes.h AESStringCrypt.h password.h security.h sha256.h libsecurity_la_SOURCES = aes.c AESStringCrypt.c password.c security.c sha256.c md5.c
libsecurity_la_CFLAGS = -I$(srcdir) LDADD = $(top_builddir)/src/libhamlib.la
LDADD = $(top_builddir)/src/libhamlib.la $(top_builddir)/security/libsecurity.la security_test_LDADD = $(LDADD)
check_PROGRAMS = security_test

310
security/md5.c 100644
Wyświetl plik

@ -0,0 +1,310 @@
#include "md5.h"
char *make_digest(const unsigned char *digest, int len) /* {{{ */
{
char *md5str = (char *) malloc(sizeof(char) * (len * 2 + 1));
static const char hexits[17] = "0123456789abcdef";
int i;
for (i = 0; i < len; i++)
{
md5str[i * 2] = hexits[digest[i] >> 4];
md5str[(i * 2) + 1] = hexits[digest[i] & 0x0F];
}
md5str[len * 2] = '\0';
return md5str;
}
/*
* The basic MD5 functions.
*
* F and G are optimized compared to their RFC 1321 definitions for
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
* implementation.
*/
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
/*
* The MD5 transformation for all four rounds.
*/
#define STEP(f, a, b, c, d, x, t, s) \
(a) += f((b), (c), (d)) + (x) + (t); \
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
(a) += (b);
/*
* SET reads 4 input bytes in little-endian byte order and stores them
* in a properly aligned word in host byte order.
*
* The check for little-endian architectures that tolerate unaligned
* memory accesses is just an optimization. Nothing will break if it
* doesn't work.
*/
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
# define SET(n) \
(*(MD5_u32plus *)&ptr[(n) * 4])
# define GET(n) \
SET(n)
#else
# define SET(n) \
(ctx->block[(n)] = \
(MD5_u32plus)ptr[(n) * 4] | \
((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
# define GET(n) \
(ctx->block[(n)])
#endif
/*
* This processes one or more 64-byte data blocks, but does NOT update
* the bit counters. There are no alignment requirements.
*/
const void *body(void *ctxBuf, const void *data, size_t size)
{
MD5_CTX *ctx = (MD5_CTX *)ctxBuf;
const unsigned char *ptr;
MD5_u32plus a, b, c, d;
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
ptr = (unsigned char *)data;
a = ctx->a;
b = ctx->b;
c = ctx->c;
d = ctx->d;
do
{
saved_a = a;
saved_b = b;
saved_c = c;
saved_d = d;
/* Round 1 */
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
/* Round 2 */
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
/* Round 3 */
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
/* Round 4 */
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
a += saved_a;
b += saved_b;
c += saved_c;
d += saved_d;
ptr += 64;
}
while (size -= 64);
ctx->a = a;
ctx->b = b;
ctx->c = c;
ctx->d = d;
return ptr;
}
void MD5Init(void *ctxBuf)
{
MD5_CTX *ctx = (MD5_CTX *)ctxBuf;
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
ctx->c = 0x98badcfe;
ctx->d = 0x10325476;
ctx->lo = 0;
ctx->hi = 0;
}
void MD5Update(void *ctxBuf, const void *data, size_t size)
{
MD5_CTX *ctx = (MD5_CTX *)ctxBuf;
MD5_u32plus saved_lo;
MD5_u32plus used, free;
saved_lo = ctx->lo;
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
{
ctx->hi++;
}
ctx->hi += size >> 29;
used = saved_lo & 0x3f;
if (used)
{
free = 64 - used;
if (size < free)
{
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, free);
data = (unsigned char *)data + free;
size -= free;
body(ctx, ctx->buffer, 64);
}
if (size >= 64)
{
data = body(ctx, data, size & ~(size_t)0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
void MD5Final(unsigned char *result, void *ctxBuf)
{
MD5_CTX *ctx = (MD5_CTX *)ctxBuf;
MD5_u32plus used, free;
used = ctx->lo & 0x3f;
ctx->buffer[used++] = 0x80;
free = 64 - used;
if (free < 8)
{
memset(&ctx->buffer[used], 0, free);
body(ctx, ctx->buffer, 64);
used = 0;
free = 64;
}
memset(&ctx->buffer[used], 0, free - 8);
ctx->lo <<= 3;
ctx->buffer[56] = ctx->lo;
ctx->buffer[57] = ctx->lo >> 8;
ctx->buffer[58] = ctx->lo >> 16;
ctx->buffer[59] = ctx->lo >> 24;
ctx->buffer[60] = ctx->hi;
ctx->buffer[61] = ctx->hi >> 8;
ctx->buffer[62] = ctx->hi >> 16;
ctx->buffer[63] = ctx->hi >> 24;
body(ctx, ctx->buffer, 64);
result[0] = ctx->a;
result[1] = ctx->a >> 8;
result[2] = ctx->a >> 16;
result[3] = ctx->a >> 24;
result[4] = ctx->b;
result[5] = ctx->b >> 8;
result[6] = ctx->b >> 16;
result[7] = ctx->b >> 24;
result[8] = ctx->c;
result[9] = ctx->c >> 8;
result[10] = ctx->c >> 16;
result[11] = ctx->c >> 24;
result[12] = ctx->d;
result[13] = ctx->d >> 8;
result[14] = ctx->d >> 16;
result[15] = ctx->d >> 24;
memset(ctx, 0, sizeof(*ctx));
}
unsigned char *make_hash(char *arg)
{
MD5_CTX context;
static unsigned char digest[65];
MD5Init(&context);
MD5Update(&context, arg, strlen(arg));
MD5Final(digest, &context);
return digest;
}
char *make_md5(char *pass)
{
unsigned char *hash = make_hash("password");
char *md5str = make_digest(hash, 16);
return md5str;
}
//#define TEST
#ifdef TEST
#include <stdio.h>
int main()
{
char *md5str = make_md5("password");
printf("md5=%s\n", md5str);
return 0;
}
#endif

55
security/md5.h 100644
Wyświetl plik

@ -0,0 +1,55 @@
#ifndef MD5_h
#define MD5_h
//#include "Arduino.h"
/*
* This is an OpenSSL-compatible implementation of the RSA Data Security,
* Inc. MD5 Message-Digest Algorithm (RFC 1321).
*
* Written by Solar Designer <solar at openwall.com> in 2001, and placed
* in the public domain. There's absolutely no warranty.
*
* This differs from Colin Plumb's older public domain implementation in
* that no 32-bit integer data type is required, there's no compile-time
* endianness configuration, and the function prototypes match OpenSSL's.
* The primary goals are portability and ease of use.
*
* This implementation is meant to be fast, but not as fast as possible.
* Some known optimizations are not included to reduce source code size
* and avoid compile-time configuration.
*/
/*
* Updated by Scott MacVicar for arduino
* <scott@macvicar.net>
*/
#include <stdlib.h>
#include <string.h>
typedef unsigned long MD5_u32plus;
typedef struct {
MD5_u32plus lo, hi;
MD5_u32plus a, b, c, d;
unsigned char buffer[64];
MD5_u32plus block[16];
} MD5_CTX;
#if 0
class MD5
{
public:
MD5();
static unsigned char* make_hash(char *arg);
static unsigned char* make_hash(char *arg,size_t size);
static char* make_digest(const unsigned char *digest, int len);
static const void *body(void *ctxBuf, const void *data, size_t size);
static void MD5Init(void *ctxBuf);
static void MD5Final(unsigned char *result, void *ctxBuf);
static void MD5Update(void *ctxBuf, const void *data, size_t size);
};
#endif
#endif

Wyświetl plik

@ -21,67 +21,62 @@
*/ */
#include <stdio.h> #include <stdio.h>
//#include <iconv.h> #include <stdlib.h>
//#include <langinfo.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "hamlib/rig.h"
#include "password.h" #include "password.h"
#ifdef NOTWORKING #define HAMLIB_SECRET_LENGTH 32
/*
* passwd_to_utf16 extern char *make_md5(char *password);
*
* Convert String to UTF-16LE for windows compatibility // makes a 32-byte secret key from password using MD5
*/ // yes -- this is security-by-obscurity
int passwd_to_utf16(char *in_passwd, // but password hacking software doesn't use this type of logic
int length, // we want a repeatable password that is not subject to "normal" md5 decryption logic
int max_length, // could use a MAC address to make it more random but making that portable is TBD
char *out_passwd) HAMLIB_EXPORT(void) rig_password_generate_secret(char *pass,
char result[HAMLIB_SECRET_LENGTH + 1])
{ {
char *ic_outbuf, unsigned int product;
*ic_inbuf; char newpass[256];
iconv_t condesc; product = pass[0];
size_t ic_inbytesleft,
ic_outbytesleft;
ic_inbuf = in_passwd; for (int i = 1; pass[i]; ++i)
ic_inbytesleft = length;
ic_outbytesleft = max_length;
ic_outbuf = out_passwd;
if ((condesc = iconv_open("UTF-16LE", nl_langinfo(CODESET))) ==
(iconv_t)(-1))
{ {
perror("Error in iconv_open"); product *= pass[i];
return -1;
} }
if (iconv(condesc, srandom(product);
&ic_inbuf,
&ic_inbytesleft,
&ic_outbuf,
&ic_outbytesleft) == -1)
{
switch (errno)
{
case E2BIG:
fprintf(stderr, "Error: password too long\n");
iconv_close(condesc);
return -1;
break;
default: snprintf(newpass, sizeof(newpass) - 1, "%s\t%lu\n", pass, random());
#if 0 printf("debug=%s\n", newpass);
printf("EILSEQ(%d), EINVAL(%d), %d\n", EILSEQ, EINVAL, errno); char *md5str = make_md5(newpass);
#endif
fprintf(stderr,
"Error: Invalid or incomplete multibyte sequence\n");
iconv_close(condesc);
return -1;
}
}
iconv_close(condesc); strncpy(result, md5str, HAMLIB_SECRET_LENGTH);
return (max_length - ic_outbytesleft);
// now that we have the md5 we'll do the AES256
printf("Shared Secret: %s\n", result);
printf("\nCan be used with rigctl --password [secret]\nOr can be place in ~/.hamlib_settings\n");
}
#define TESTPASSWORD
#ifdef TESTPASSWORD
int main(int argc, char *argv[])
{
char secret[HAMLIB_SECRET_LENGTH + 1];
char password[HAMLIB_SECRET_LENGTH +
1]; // maximum length usable for password too
// anything longer will not be used to generate the secret
if (argc == 1) { strcpy(password, "testpass"); }
else { strcpy(password, argv[1]); }
printf("Using password \"%s\" to generate shared key\n", password);
rig_password_generate_secret(password, secret);
return 0;
} }
#endif #endif

Wyświetl plik

@ -2080,11 +2080,11 @@ int HAMLIB_API rig_set_mode(RIG *rig, vfo_t vfo, rmode_t mode, pbwidth_t width)
} }
} }
if (retcode != RIG_OK) if (retcode != RIG_OK)
{ {
rig_debug(RIG_DEBUG_TRACE, "%s: failed set_mode(%s)=%s\n", rig_debug(RIG_DEBUG_TRACE, "%s: failed set_mode(%s)=%s\n",
__func__, rig_strrmode(mode), rigerror(retcode)); __func__, rig_strrmode(mode), rigerror(retcode));
RETURNFUNC(retcode); RETURNFUNC(retcode);
} }
rig_set_cache_mode(rig, vfo, mode, width); rig_set_cache_mode(rig, vfo, mode, width);
@ -7108,15 +7108,14 @@ void *async_data_handler(void *arg)
} }
#endif #endif
HAMLIB_EXPORT(int) rig_password(RIG *rig, const unsigned char *key1, HAMLIB_EXPORT(int) rig_password(RIG *rig, const char *key1)
const unsigned char *key2)
{ {
int retval = -RIG_ENIMPL; int retval = -RIG_EPROTO;
ENTERFUNC; ENTERFUNC;
if (rig->caps->password != NULL) if (rig->caps->password != NULL)
{ {
retval = rig->caps->password(rig, key1, key2); retval = rig->caps->password(rig, key1);
//retval = RIG_OK; //retval = RIG_OK;
} }

Wyświetl plik

@ -96,7 +96,7 @@ extern int read_history();
static int chk_vfo_executed; static int chk_vfo_executed;
char rigctld_password[64]; char rigctld_password[64];
int is_passwordOK; int is_passwordOK;
int is_rigctld; int is_rigctld;
@ -245,7 +245,7 @@ declare_proto_rig(get_cache);
declare_proto_rig(halt); declare_proto_rig(halt);
declare_proto_rig(pause); declare_proto_rig(pause);
declare_proto_rig(password); declare_proto_rig(password);
declare_proto_rig(set_password); //declare_proto_rig(set_password);
declare_proto_rig(set_clock); declare_proto_rig(set_clock);
declare_proto_rig(get_clock); declare_proto_rig(get_clock);
@ -354,7 +354,7 @@ static struct test_table test_list[] =
{ 0xf1, "halt", ACTION(halt), ARG_NOVFO }, /* rigctld only--halt the daemon */ { 0xf1, "halt", ACTION(halt), ARG_NOVFO }, /* rigctld only--halt the daemon */
{ 0x8c, "pause", ACTION(pause), ARG_IN, "Seconds" }, { 0x8c, "pause", ACTION(pause), ARG_IN, "Seconds" },
{ 0x98, "password", ACTION(password), ARG_IN | ARG_NOVFO, "Password" }, { 0x98, "password", ACTION(password), ARG_IN | ARG_NOVFO, "Password" },
{ 0x99, "set_password", ACTION(set_password), ARG_IN | ARG_NOVFO, "Password" }, // { 0x99, "set_password", ACTION(set_password), ARG_IN | ARG_NOVFO, "Password" },
{ 0xf7, "get_mode_bandwidths", ACTION(get_mode_bandwidths), ARG_IN | ARG_NOVFO, "Mode" }, { 0xf7, "get_mode_bandwidths", ACTION(get_mode_bandwidths), ARG_IN | ARG_NOVFO, "Mode" },
{ 0x00, "", NULL }, { 0x00, "", NULL },
}; };
@ -1704,10 +1704,13 @@ readline_repeat:
{ {
rig_debug(RIG_DEBUG_ERR, "%s: need password=%s for cmd=%s\n", __func__, rig_debug(RIG_DEBUG_ERR, "%s: need password=%s for cmd=%s\n", __func__,
rigctld_password, cmd_entry->arg1); rigctld_password, cmd_entry->arg1);
return (-RIG_EPROTO); fflush(fin);
retcode = -RIG_EPROTO;
} }
retcode = (*cmd_entry->rig_routine)(my_rig, else
{
retcode = (*cmd_entry->rig_routine)(my_rig,
fout, fout,
fin, fin,
interactive, interactive,
@ -1721,6 +1724,7 @@ readline_repeat:
p1, p1,
p2 ? p2 : "", p2 ? p2 : "",
p3 ? p3 : ""); p3 ? p3 : "");
}
if (retcode == -RIG_EIO) if (retcode == -RIG_EIO)
@ -4934,15 +4938,18 @@ declare_proto_rig(pause)
return (RIG_OK); return (RIG_OK);
} }
int rigctld_password_check(RIG *rig, const unsigned char *key1, extern char *make_md5(char *password);
const unsigned char *key2)
int rigctld_password_check(RIG *rig, const char *md5)
{ {
int retval = -RIG_EINVAL; int retval = -RIG_EINVAL;
//fprintf(fout, "password %s\n", password); //fprintf(fout, "password %s\n", password);
rig_debug(RIG_DEBUG_TRACE, "%s: %s == %s\n", __func__, key1, rigctld_password); rig_debug(RIG_DEBUG_TRACE, "%s: %s == %s\n", __func__, md5, rigctld_password);
is_passwordOK = 0; is_passwordOK = 0;
if (strcmp((char *)key1, rigctld_password) == 0) char *mymd5 = make_md5(rigctld_password);
if (strcmp(md5, mymd5) == 0)
{ {
retval = RIG_OK; retval = RIG_OK;
is_passwordOK = 1; is_passwordOK = 1;
@ -4955,34 +4962,35 @@ int rigctld_password_check(RIG *rig, const unsigned char *key1,
declare_proto_rig(password) declare_proto_rig(password)
{ {
int retval = -RIG_EPROTO; int retval = -RIG_EPROTO;
const char *passwd = arg1; const char *key = arg1;
ENTERFUNC; ENTERFUNC;
if (is_rigctld) if (is_rigctld)
{ {
retval = rigctld_password_check(rig, (unsigned char *)passwd, (unsigned char*)"key2"); retval = rigctld_password_check(rig, key);
} }
else else
{ {
retval = rig_password(rig, (unsigned char *) passwd, (unsigned char *)"key2"); retval = rig_password(rig, key);
//retval = RIG_OK; //retval = RIG_OK;
} }
if (retval == RIG_OK) if (retval == RIG_OK)
{ {
rig_debug(RIG_DEBUG_ERR, "%s: #1 password OK\n", __func__); rig_debug(RIG_DEBUG_ERR, "%s: #1 password OK\n", __func__);
fprintf(fout, "Logged in\n"); //fprintf(fout, "Logged in\n");
} }
else else
{ {
rig_debug(RIG_DEBUG_ERR, "%s: password error, '%s'!='%s'\n", __func__, rig_debug(RIG_DEBUG_ERR, "%s: password error, '%s'!='%s'\n", __func__,
passwd, rigctld_password); key, rigctld_password);
} }
RETURNFUNC(retval); RETURNFUNC(retval);
} }
#if 0 // don't think we need this yet
/* 0x99 */ /* 0x99 */
declare_proto_rig(set_password) declare_proto_rig(set_password)
{ {
@ -4991,6 +4999,7 @@ declare_proto_rig(set_password)
rig_debug(RIG_DEBUG_ERR, "%s: set_password %s\n", __func__, rigctld_password); rig_debug(RIG_DEBUG_ERR, "%s: set_password %s\n", __func__, rigctld_password);
return (RIG_OK); return (RIG_OK);
} }
#endif
/* '0x8d' */ /* '0x8d' */
declare_proto_rig(set_twiddle) declare_proto_rig(set_twiddle)

Wyświetl plik

@ -149,7 +149,7 @@ const char *portno = "4532";
const char *src_addr = NULL; /* INADDR_ANY */ const char *src_addr = NULL; /* INADDR_ANY */
const char *multicast_addr = "0.0.0.0"; const char *multicast_addr = "0.0.0.0";
int multicast_port = 4532; int multicast_port = 4532;
extern char rigctld_password[64]; extern char rigctld_password[65];
#define MAXCONFLEN 1024 #define MAXCONFLEN 1024
@ -238,6 +238,8 @@ static void handle_error(enum rig_debug_level_e lvl, const char *msg)
} }
extern char *make_md5(char *password);
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
rig_model_t my_model = RIG_MODEL_DUMMY; rig_model_t my_model = RIG_MODEL_DUMMY;
@ -306,6 +308,8 @@ int main(int argc, char *argv[])
case 'A': case 'A':
strncpy(rigctld_password, optarg, sizeof(rigctld_password) - 1); strncpy(rigctld_password, optarg, sizeof(rigctld_password) - 1);
char *md5 = make_md5(rigctld_password);
printf("Secret key: %s\n", md5);
break; break;
case 'm': case 'm':
@ -1061,20 +1065,24 @@ int main(int argc, char *argv[])
#ifdef HAVE_PTHREAD #ifdef HAVE_PTHREAD
/* allow threads to finish current action */ /* allow threads to finish current action */
mutex_rigctld(1); mutex_rigctld(1);
TRACE;
if (client_count) if (client_count)
{ {
rig_debug(RIG_DEBUG_WARN, "%u outstanding client(s)\n", client_count); rig_debug(RIG_DEBUG_WARN, "%u outstanding client(s)\n", client_count);
} }
rig_close(my_rig); rig_close(my_rig);
TRACE;
mutex_rigctld(0); mutex_rigctld(0);
TRACE;
#else #else
rig_close(my_rig); /* close port */ rig_close(my_rig); /* close port */
#endif #endif
TRACE;
network_multicast_publisher_stop(my_rig); network_multicast_publisher_stop(my_rig);
TRACE;
rig_cleanup(my_rig); /* if you care about memory */ rig_cleanup(my_rig); /* if you care about memory */
#ifdef __MINGW32__ #ifdef __MINGW32__