|
So conclusion is we can't use qc3...?
On Fri, Nov 22, 2019, 18:57 Bruce Vining <bruce.vining@xxxxxxxxx> wrote:
Hi, Mark
Good to hear from you, it's been a while. I was aware of those (and a few
other) offerings. That's what prompted me to add the "nothing within the
i
operating system itself" qualifier (in my mind meaning the base OS).
On Fri, Nov 22, 2019 at 12:33 PM Mark Waterbury <
mark.s.waterbury@xxxxxxxxxxxxx> wrote:
Hi, Bruce,https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_72/rzaie/apr_core_api/group___a_p_r___util___base64.html
Well, ... there is this:
and this:https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/apis/qc3decdt.htm
http://www.scottklement.com/base64/
All the best,
Mark S. Waterbury
On Friday, November 22, 2019, 12:18:39 PM EST, Bruce Vining <
bruce.vining@xxxxxxxxx> wrote:
When you construct the cmd variable you specify:
-aes-128-ecb
so we know it's aes with 128 bit keys and ecb
Now let's look at the qc3DecryptData API at
.and
If we look at the Algorithm description format name parameter we see it
supports AES with format ALGD0200. If we look at the Block cipher
algorithm element of format ALGD0200 we see a value of 22 means use AES
a Mode element value of 0 means ECB. If we look at the If we look atthe
Key description format name parameter we see it supports format KEYD0200type
which supports AES with a Key type value of 22. Further that with key
22 the key string length or derived key length can be 16, 24, or 32.This
is in bytes so a value of 16 is equivalent to a bit count of 128.first
cmd also specifies:
-base64
The qc3DecryptData API does not support base64 so you would need to
decode the XML base64 value and then use that decoded value as input towrote:
qc3DecryptData. Unfortunately looking (very briefly) at the enc
documentation it doesn't (readily) specify the implementation of base64
it's using. There are various base64 encode/decode utilities around for
the i, but nothing within the i operating system itself.
On Fri, Nov 22, 2019 at 11:43 AM Rishi Seth <rishiseth99@xxxxxxxxx>
etc.)
......putting
....XML file in my previous email ,so could it be confirmed whether
these below changes will take care of all future junk values(DLEs
thiswhich might come in the decrypted value?
or some other error handling conditions we need to incorporate in
likecode to take care of such unforeseen DLEs or some other junk values?not
pos2 = %scan(x'10' :record);
Record = %subst(Record :1 :(Pos2 - 1));
...Also as we did not know that how the data was encrypted so we could
use Qc3DecryptData API here but as per experts on this forum i would
algorithmto confirm one again since we don't know how the data is encrypted
so we can not use Qc3DecryptData API to decrypt it using AES128
wellneither we can use sql decrypt function due to it's limits also as wehave
used openssl here and saw these DLEs here so shared XML file here as
itconsidering possibility data itself is junk or having DLEs inside in
soprogram
could you please confirm whether it's XML issue only now?
If yes ,then what above said changes we have incorporated in our
regardingthen it should be sufficient enough to handle all those DLEs errorswrote:
Thanks much...
Thanks
On Fri, Nov 22, 2019 at 5:22 PM Rishi Seth <rishiseth99@xxxxxxxxx>
ok,that key hardcoding issue is resolved now thanks much but
bruce.vining@xxxxxxxxx>those DLEs as i have shared sample
On Fri, Nov 22, 2019 at 5:01 PM Bruce Vining <
<encodedExchangeToken>u3VtNgfyWU9faZc3Iaa8ZWbE5UZCfmC17yA4MyW0ghflt9dNQNDpCcgMZiG/kXPE4vv2CHL93B4iKiODHxxdVA==---reply.wrote:
-- cmd = 'echo ' + '''' + encodedExchangeToken + ''' ! openssl +
-- enc -d -aes-128-ecb -K 363631653237354f494d31554c594c4a +
-- -nopad -nosalt -base64 -A';
The above does NOT represent the changes suggested in my previous
I
would have expected to see something like
...-K ' + KEY + ' -nopad...
The provided text still has the key value as a literal.
--
seebytes,</encodedExchangeToken>
You have confirmed that the XML file contains the "extra" 16 bytes.
Who/what provided this value? This line indicates to ship those 16
which are being decoded and decrypted into DLEs. From what I can
source...everything is working just like one would expect given this
errors:-
On Fri, Nov 22, 2019 at 10:42 AM Rishi Seth <rishiseth99@xxxxxxxxx
wrote:
ok,thanks tried as per below now and when ran it got below
small99
cmd = 'echo ' + '''' + encodedExchangeToken + ''' ! openssl +
enc -d -aes-128-ecb -K 363631653237354f494d31554c594c4a +
-nopad -nosalt -base64 -A';
**************************************************************
Additional Message Information
Message ID . . . . . . : RNQ0103 Severity . . . . . . . :
Message type . . . . . : Inquiry
Date sent . . . . . . : 19-11-22 Time sent . . . . . . :
15:40:09
Message . . . . : The target for a numeric operation is too
valueto
hold
the result (C G D F).
Cause . . . . . : RPG procedure DCR19 in program RISHI/DCR19 at
statement
113 performed an arithmetic operation which resulted in a
thethat
is
too
large to fit in the target. If this is a numeric expression,
. .result.overflow
could be the result of the calculation of some intermediate
maintenance
Recovery . . . : Contact the person responsible for program
to
determine the cause of the problem.
Possible choices for replying to message . . . . . . . . . . .
.assistance
.
:
D -- Obtain RPG formatted dump.
S -- Obtain system dump.
F -- Obtain full formatted dump.
More...
Press Enter to continue.
F3=Exit F6=Print F9=Display message details
F10=Display messages in job log F12=Cancel F21=Select
at40level
***********************************************************
Additional Message Information
Message ID . . . . . . : CPF9999 Severity . . . . . . . :
Message type . . . . . : Escape
Date sent . . . . . . : 19-11-22 Time sent . . . . . . :
15:40:09
Message . . . . : Function check. MCH1210 unmonitored by DCR19
program toprogramstatement
0000000113, instruction X'0000'.
Cause . . . . . : An escape exception message was sent to a
which
did not monitor for that message. The full name of the
shown,thewhich
the
unmonitored message was sent is DCR19 DCR19 DCR19. At the time
statementmessage
was sent the program was stopped at higher level language
number(s) 0000000113. If more than one statement number is
singlethe
program was a bound program. Optimization does not allow a
thestatement
number to be determined. If *N is shown as a value, it means
toactual
value was not available.
Recovery . . . : See the low level messages previously listed
botherthelocate
the
cause of the function check. Correct any errors, and then try
request
More...
Press Enter to continue.
*********
And if XML is causing those DLEs then I think i need not to
asDLEs
wethose
have put below changes so i think it will take care care of all
unforeseen junk(DLEs).
pos2 = %scan(x'10' :record);
Record = %subst(Record :1 :(Pos2 - 1));
please correct me if i am wrong and below is requested xml for
<encodedExchangeToken>u3VtNgfyWU9faZc3Iaa8ZWbE5UZCfmC17yA4MyW0ghflt9dNQNDpCcgMZiG/kXPE4vv2CHL93B4iKiODHxxdVA==</encodedExchangeToken>analysis>/http://schemas.nav.gov.hu/OSA/1.0/data"
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
-<TokenExchangeResponse xmlns:ns2="
xmlns="http://schemas.nav.gov.hu/OSA/1.0/api">
-<header>
<requestId>XXXXXXX6614</requestId>
<timestamp>2019-10-22T09:53:40.541Z</timestamp>
<requestVersion>1.1</requestVersion>
<headerVersion>1.0</headerVersion>
</header>
-<result>
<funcCode>OK</funcCode>
</result>
-<software>
<softwareId>R1RL002AAAAAAAAAAA</softwareId>
<softwareName>string</softwareName>
<softwareOperation>LOCAL_SOFTWARE</softwareOperation>
<softwareMainVersion>string</softwareMainVersion>
<softwareDevName>string</softwareDevName>
<softwareDevContact>string</softwareDevContact>
<softwareDevCountryCode>HU</softwareDevCountryCode>
<softwareDevTaxNumber>string</softwareDevTaxNumber>
</software>
<tokenValidityFrom>2019-10-22T11:57:16.646+02:00</tokenValidityFrom>
andbruce.vining@xxxxxxxxx>
<tokenValidityTo>2019-10-22T12:02:16.646+02:00</tokenValidityTo>
</TokenExchangeResponse>
Thanks
On Fri, Nov 22, 2019 at 3:00 PM Bruce Vining <
wrote:
You have KEY within the quoted string starting with ! openssl
information,KEYending
with -A';
End the quoted string prior to KEY and then resume it following
(and
add + before and after so everything is nicely concatenated...)
As for the DLEs, again I have to, based on provided
writing/constructionassume
the
XML file is the source -- that is, whoever is
rishiseth99@xxxxxxxxxthe
XML.
On Fri, Nov 22, 2019 at 8:20 AM Rishi Seth <
myfile
wrote:
Hi,
I tried below code in which i have kept hex value of key in a
called
k1 and field called key in this file but the problem is that
checkprogram
is
able to read key value from this file but the moment
i try to execute this cmd command inside my program and
thevalue
value....5...10...15...20...25...30...35...40...45...50...55...60
of
cmd field in debug mode i get it like below :-
EVAL cmd
CMD =
'jkYrd7QTBwv6ghTV0SnrqCdwJ8TnpZAk8+oVlNXwt7aDHoJSQWBsh4'1 'echo
-aes-12'61 'R7cggjSc+34vv2CHL93B4iKiODHxxdVA==' ! openssl enc -d
'121 '8-ecb -K key -nopad -nosalt -base64 -A
'181 '
'241 '
i was expecting like it took encodedexchangetoken field
valuefrom
that
xml file using xml into builtin function and showing it's
infield's
encodedexchangetoken field.
but when i read file in my code it does not pick the key
field'svalue
from
this below code i am just wondering how can i pass key
USROPNvalue to
openssl command rather than hardcoding inside my program.
*******
FUNIX IF F 1000 SPECIAL PGMNAME('UNIXCMD')
F PLIST(UNIXPARM)
=%trimr(encodedExchangeToken);fk1 if e disk
F*QSYSPRT O F 1000 PRINTER
dencodedExcha...
dngeToken s 500 VARYING
DPOS2 S 5U 0
D cmd s 5000a
D mode s 1A inz('P')
DN1 S 2P 0
D Åcommand s 512a
d QCMDEXC PR ExtPgm('QCMDEXC')
d command 500a const
d clength 15p 5 const
D record ds 1000
D outrec s 1000 varying inz
C UNIXPARM PLIST
C PARM CMD
C PARM MODE
/free
RECORD = *BLANKS;
OUTREC = *BLANKS;
XML-INTO encodedExchangeToken %XML('/home/I0RS01HU/+
IN2.xml':'doc=file case=any path=+
TokenExchangeResponse/encodedExchangeToken');
eval encodedExchangeToken
useopensslREAD rec;
dsply key;
cmd = 'echo ' + '''' + encodedExchangeToken + ''' !
rishiseth99@xxxxxxxxx>+
%char(N1) +enc -d -aes-128-ecb -K KEY +
-nopad -nosalt -base64 -A';
open UNIX;
read UNIX record;
dow not %eof(UNIX);
pos2 = %scan(x'10' :record);
Record = %subst(Record :1 :(Pos2 - 1));
eval outrec = %trimr(record);
EVAL N1 = %LEN(OUTREC);
DSPLY N1;
//Delete the TESTFILE
Åcommand = 'DLTF FILE(rishi/TESTFILE)';
QCMDEXC(%trim(Åcommand): %len(%trim(Åcommand)));
Åcommand = *blanks;
Åcommand = 'CRTPF FILE(RISHI/TESTFILE) RCDLEN(' +
')';
QCMDEXC(%trim(Åcommand): %len(%trim(Åcommand)));
//Write into file
EXEC SQL
INSERT INTO rishi/TESTFILE VALUES (:outrec);
// dsply %subst(outrec:1:48);
read UNIX record;
enddo;
close UNIX;
return;
/end-free
Thanks
On Thu, Nov 21, 2019 at 11:38 PM Rishi Seth <
wrote:
Ok, thanks for these details,
Is it possible not to hardcode the key value used here and
timeit
as
a
variable field like field of some file etc.so that each
notonce
key
is
changed we may not have to change the program code and do
thattargetneed to
recompile it?
Also in input XML we were not focused on other field's only
was
just to fetch this 'encodedexchangetoken' field out of
XMLfine
file
decryptedand
whatever data comes inside this field that should have been
using
AES 128 Algorithm so far this program seems to be working
junkonly
thing i
was worried because of DLEs but could there be some more
thoughtcan'tvalues
might
come like these DLEs in decrypted value, Which currently we
imagine
and låter on this program might crash as we have not
of(Or
or
have
not
considered handling regarding those probable junk values
soQc3DecryptData.
bruce.vining@xxxxxxxxx>called
some other type of DLEs etc.) as of now?
Thanks much.....
On Thu, Nov 21, 2019, 21:17 Bruce Vining <
wrote:
I did not get around to actually trying out
told me
Yesterday the DLEs in the debug eval of record really
realizedall I
needed
to know. This morning I looked more at the debug eval
of encodedExchangeToken, saw the leading x'0058' and
XML-INTOyou
had
it
defined as varying length. That value tells me that
base64returned
88
bytes and the -base64 argument to enc told me it was
Thetwoindicating
the
actual length received (based64 decoded) was 66 bytes with
trailing
pad
characters (the == from record) leaving 64 "real" bytes.
requestedsomesuchmaybelast
16
bytes
(the DLEs) then must have been in the original stream (OK,
AES
decryption and base64 decoding uses DLEs for errors or
casethough
I've
never seen that behavior or found it documented). In any
receiving"someone"
is
adding 16 bytes to encodedExchangeToken prior to your
it
with
XML-INTO. As you did not provide the XML file (as
it'swith 8.
Post
the contents of /home/I0RS01HU/INPUT.xml) I'm assuming
neverthere in
the
file and that XML-INTO didn't add it (an add which I've
botherseen
and I
have played with it, XML-INTO, in the past).
As you now have it working with openssl enc I wouldn't
Isomewhatchanging.
Personally I use the i cryptographic APIs (but I'm also
biased
when it comes to system APIs) when doing development.
When the SQL encrypt and decrypt functions first came out
didsomeone
wholetake a
quick look at them and immediately saw that there were a
notlot
of
features (that I sometimes use) that the SQL interfaces do
support.
So
I would not use them unless forced to -- meaning that
appears towasnever
sending
me data encrypted using say ENCRYPT_AES. To date I have
run
into
that situation.
I do however wonder why base64 is being used as it
abe
paddingtext
data
being exchanged (with the exception of the DLEs) and what
might
be
done if say the "real" data was only 45 bytes rather than
timemultiple
rishiseth99@xxxxxxxxx>of
16
such as 48.
Hope this helps,
On Thu, Nov 21, 2019 at 10:09 AM Rishi Seth <
interactivelywrote:
Hi,
How could we say or conclude so because whenever i
call
openssl command the same DLE seems to be coming that
asfield
whichwell
in
the
result of pase ?
so does this mean xml itself is faulty i mean the value
is
supplied
in XML (specially data in that encodedexchangetoken
indecryption
forprogramthat
XML
file
itself is faulty ?)
secondly were you able to run that 'Qc3DecryptData' API
successfully could you please share your program example
current
case
as i tried to use Qc3DecryptData API for same
how(Using
AES128
Algorithm) but it did not work because i did not know
thedid
data
was
encrypted only decryption thing i was focused on, as i
thatnot
knowfunction
how
the
data was encoded so may be those sql encrypt and decrypt
also
did
not work for this case also when you would have used
differentQc3DecryptData
API was your program capable to handle each time
functionXML
builtinfiles
data
like the one which i shared was having XML into kind of
Qc3DecryptData'functions
so it was capable to handle those different XMLs.
1) If same decrypted value could be achived using
API
Could you please share that program code example ?
2) Can same result be achieved using SQL Decrypt
asreceived.
these 3well
if
yes
then could you please share that as well?
3) Which way should be best technically among of all
openssl,approaches
in case same decrypted value could be achieved using
bruce.vining@xxxxxxxxx>Qc3DecryptData API,SQL Decrypt function ?
Thanks much...
On Thu, Nov 21, 2019 at 1:44 PM Bruce Vining <
wrote:
The DLEs are in the original XML stream being
thebruce.vining@xxxxxxxxx>
On Wed, Nov 20, 2019 at 3:17 PM Bruce Vining <
wrote:
Since Rishi has provided the encrypted stream and
keyshould be
I'll,
if I
find
the time (which as I'm currently free of work
inpossible),
decrypt
using Qc3DecryptData and at least find out if it's
theof
insertingstreaminterface...
or
being
added later when running cmd through the UNIXCMD
sk@xxxxxxxxxxxxxxxx>
On Wed, Nov 20, 2019 at 1:12 PM Scott Klement <
wrote:
The other possibility is that the PASE shell is
them,
maybe
thinking it needs to escape something for the sake
aRPG400-L@xxxxxxxxxxxxxxxxxx
haveterminal?
On 11/20/2019 9:32 AM, Bruce Vining wrote:
As I cannot imagine Scott inserting those DLEs I
tomailing
assume
they
are in
the XML document.--
This is the RPG programming on IBM i (RPG400-L)
list
To post a message email:
amazon.comsubscriptionhttps://lists.midrange.com/mailman/listinfo/rpg400-lTo subscribe, unsubscribe, or change list options,
visit:
archivesor email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the
at https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any
related
questions.
Help support midrange.com by shopping at
mailingwith
our
affiliate
link: https://amazon.midrange.com
--
Thanks and Regards,
Bruce
931-505-1915
--
Thanks and Regards,
Bruce
931-505-1915
--
This is the RPG programming on IBM i (RPG400-L)
subscriptionlistarchives
https://lists.midrange.com/mailman/listinfo/rpg400-lTo post a message email: RPG400-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit:
or email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the
at https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any
withrelated
questions.
Help support midrange.com by shopping at amazon.com
archivesourlist
affiliate
link: https://amazon.midrange.com--
This is the RPG programming on IBM i (RPG400-L) mailing
https://lists.midrange.com/mailman/listinfo/rpg400-lTo post a message email: RPG400-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit:
or email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the
subscriptionat https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any
withrelated
questions.
Help support midrange.com by shopping at amazon.com
ourlist
affiliate
link: https://amazon.midrange.com
--
Thanks and Regards,
Bruce
931-505-1915
--
This is the RPG programming on IBM i (RPG400-L) mailing
https://lists.midrange.com/mailman/listinfo/rpg400-lTo post a message email: RPG400-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit:
archivesor email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the
ourrelatedat https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription
questions.
Help support midrange.com by shopping at amazon.com with
relatedrelatedaffiliate
--link: https://amazon.midrange.com
This is the RPG programming on IBM i (RPG400-L) mailing list
To post a message email: RPG400-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: https://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription
affiliatequestions.
Help support midrange.com by shopping at amazon.com with our
link: https://amazon.midrange.com
--
Thanks and Regards,
Bruce
931-505-1915
--
This is the RPG programming on IBM i (RPG400-L) mailing list
To post a message email: RPG400-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: https://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription
affiliateaffiliateaffiliateaffiliatequestions.
Help support midrange.com by shopping at amazon.com with our
link: https://amazon.midrange.com--
This is the RPG programming on IBM i (RPG400-L) mailing list
To post a message email: RPG400-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: https://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription related
questions.
Help support midrange.com by shopping at amazon.com with our
link: https://amazon.midrange.com
--
Thanks and Regards,
Bruce
931-505-1915
--
This is the RPG programming on IBM i (RPG400-L) mailing list
To post a message email: RPG400-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: https://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription related
questions.
Help support midrange.com by shopping at amazon.com with our
--link: https://amazon.midrange.com
This is the RPG programming on IBM i (RPG400-L) mailing list
To post a message email: RPG400-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: https://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription related
questions.
Help support midrange.com by shopping at amazon.com with our
link: https://amazon.midrange.com
--
Thanks and Regards,
Bruce
931-505-1915
--
This is the RPG programming on IBM i (RPG400-L) mailing list
To post a message email: RPG400-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: https://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription related
questions.
Help support midrange.com by shopping at amazon.com with our affiliate
link: https://amazon.midrange.com
--
This is the RPG programming on IBM i (RPG400-L) mailing list
To post a message email: RPG400-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: https://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription related
questions.
Help support midrange.com by shopping at amazon.com with our affiliate
link: https://amazon.midrange.com
--
Thanks and Regards,
Bruce
931-505-1915
--
This is the RPG programming on IBM i (RPG400-L) mailing list
To post a message email: RPG400-L@xxxxxxxxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: https://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives
at https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription related
questions.
Help support midrange.com by shopping at amazon.com with our affiliate
link: https://amazon.midrange.com
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.