you guys didnt want an actual break did you? =)
(on a side note: i am finally considering getting a Mac for some
development work, so perhaps i will be able to help out with the GNTP
stuff in a more productive way than just pestering about it. since i
have never owned a Mac before, do you think a Mini would be sufficient
if all i wanted to do was some part-time development? i wont be
watching movies or encoding video or running apps or really doing
anything other than compiling XCode. i already have a nice spare
monitor, so i was wondering if a Mini would cut it of it i need an
iMac. thoughts from the experts?)
About the only thing a mini might fail at is playing 3D video games.
(And maybe not even that, since it's not using Intel onboard video
anymore.)
Definitely stock up on RAM, though. If you don't mind performing a
little surgery, order the Mac with 1 GB, and buy the RAM from Other
World Computing:
<http://eshop.macsales.com/item/Other%20World%20Computing/
8566DDR3S4GP/>
They charge a little over half what Apple does.
RAM is the only critical thing anymore. Any Mac made in the last few
years will work just fine as long as it has enough RAM.
For the Mac itself, you might consider the online Apple Store's
refurbished section. Right now, they have a low-end current-model Mac
mini for $499 ($100 off new).
thanks for the tip, Peter. i think the refurbed Mini with some extra
RAM is the ticket then.
is that the Google Code repository? i took a quick look at the
available branches and, although there were quite a few branches in
there, i didnt see an GNTP branch.
actually, after looking some more, it looks like the Google Code
source is maybe not the 'official' repository quite yet - i did see
some promising stuff at http://growl.info/hg/growl-development, but i
am completely new to hg / Mercurial so i need to poke around some
more.
> mac to mac works here. unsurprisingly mac to windows and
> windows to mac does not work ;)
when i checked last, Evan's last commits were from almost a year ago.
the GNTP spec changed a bit since then (via discussions in this
group), and some of the remaining stuff i implemented in the Windows
version was never officially decided upon (but i took the liberty of
forging ahead anyway), so it makes sense that it might not be
compatible at the moment. it should be pretty close though.
i am more than willing to jump in on this and help get it sorted, but
i 1) still need to get a Mac to develop on, and 2) need to familiarize
myself with your source control system/procedures (i have seen Peter's
guides, so i just need to take the time to work through them once my
dev environment is set up).
thanks for the update - i know this is only one of many things on your
plates, but it is exciting for me just the same.
all of the changes that we discussed that never made it into the
original working document are included in this version:
http://www.growlforwindows.com/gfw/help/gntp.aspx - that also includes
any additional items that i had to sort out on my own. essentially,
that is the spec that Growl for Windows is built to (minus one or two
things that are noted as being omitted at this point).
recently, Evan suggested that we just use the GfW version of the spec
if it has been hammered out and working in real-world situations. if
that is the case, there are a bunch of client libraries in various
languages that can also be used to test out the implementation:
http://www.growlforwindows.com/gfw/developers.aspx#integration . i
also have a suite of test cases that can be run against a GNTP
listener to check the implementation - it is a little bit old, but all
of the major functionality and exception cases are covered.
as for specific things that may have changed since Evan's last commits:
- security
we talked about a few ways of doing this and i finally just
implemented something that worked well. it is pretty straight-forward
and documented in the spec, but we need to get non-encrypted
communication working first.
- socket reuse (GNTP/1.0 END semaphore)
we decided that socket reuse would be allowed, but the default was no
socket reuse. to enable socket reuse, the Connection: Keep-Alive
header must be sent by the client. if it is sent, then the GNTP/1.0
END termination message must also be sent (instead of using the normal
<CRLF><CRLF> terminator. (note that this is documented in the spec,
but GfW does not yet support socket re-use)
- app-specific data headers
we didnt officially decide on a name, but the sentiment seemed to be
that simpler was better, so i went with the 'Data-*' prefix for
headers that would be passed back to the sender (not to be confused
with X-* headers that are for extending the GNTP spec/functionality).
there might have been a few other minor name changes here and there,
but for the most part, these were the big ones.
two things i notice:
1. the GNTP header line should only have 'NONE' one time. if the key
is not sent, the entire algorithm/keyhash/salt portion should be
omitted
2. since the Connection: Keep-Alive header was not sent in the
original request, socket reuse should not be used. as such, the
GNTP/1.0 END marker is not allowed.
a valid response would look like this:
GNTP/1.0 -OK NONE
Subscription-TTL: 300
Response-Action: SUBSCRIBE
to hopefully make is simpler, i am attaching the raw tests for you to
use. each text file is a GNTP request, so you can send each one and
log the response to see if it is returning what you believe to be the
correct response. these tests only test REGISTER and NOTIFY (since
they were written before SUBSCRIBE even existed), and i believe they
only test non-encrypted communications. but it is helpful to test
various edge cases and known working cases.
> I just started digging into the code and it looks like its more than
> just those couple things that weren't implemented yet. I see no sign
> of SUBSCRIBE handling (which would explain why gfw fails to connect
> for that, growl never sends back the response its expecting to get.)
yeah, i totally forgot about SUBSCRIBE since i wasnt sure when it was
added. i reviewed some older threads in this group and realized that
both SUBSCRIBE and the Data-* headers were discussed later than i
thought. the SUBSCRIBE documentation should be up-to-date in the
version of the spec i linked to.
> it also doesn't look like the spec makes any mention to Data-, just
> X-.
i dont know why i didnt add them to the spec. at one point, i was
considering not supporting any app-specific headers at all, so maybe i
just forgot to go back and document them? anyway, GfW does support
Data-* headers. an app can send any Data-* headers it wants and they
will be returned to the app in the GNTP -OK and -CALLBACK responses,
unmodified by Growl. they are just used for the app to attach
additional information that it might need later as a convenience. i
will add the relevant section to the online spec.
> gfw does successfully send notifications to the mac, counter to
> previous statement of nothing working.
yay! i know there are lots of little things to iron out, but from my
little review of things (cant actually run the OSX code yet), it looks
pretty close. it will be a very satisfying day when Mac-Win and
Win-Mac communication is working seamlessly.
i finally got a chance to look at the code and it was definitely a bug
on my end as you suspected. i committed the fix so if you are building
from source, you should be able to grab Rev. 92 and try that out. (i
didnt have a machine that was sending a chunked response to test
against, but i believe the fix should do the trick).
i double checked, and the GfW code and the online GNTP spec document
dont match up on this one. GfW recognizes the
Notification-Coalescing-ID header (although it currently doesnt
actually coalesce anything), but the spec document has combined the
Notification-ID header with the Notification-Coalescing-ID header:
Notification-ID: <string>
Optional - A unique ID for the notification. If present, serves as a
hint to the notification system that this notification should replace
any existing on-screen notification with the same ID. This can be used
to update an existing notification. The notification system may ignore
this hint.
that was just a mistake in publishing the spec. i will update the spec
to reflect the correct usage. just out of curiosity though, does
anyone think confusion could arise from the similarities between the
two headers? will developers (incorrectly) set the Notification-ID
header for a replacement notification and wonder why it doesnt work?
i was about to update the GNTP spec to reflect the correct usage of
Notification-ID and Notification-Coalescing-ID and just wanted to get
clarification on a couple of things:
1. the only way to update a notification using
Notification-Coalescing-ID is if the original notification had
previously set/sent the Notification-Coalescing-ID header as well,
correct?
2. there is no way to update an existing notification if the original
did not specify the Notification-Coalescing-ID header?
in a discussion earlier in this group, i had written the comment
below. when i published the updated GNTP spec, i included these
changes even though GfW's code still recognizes the
Notification-Coalescing-ID header too.
"Should we consider just combining these? From the application's
standpoint, is it confusing to have essentially two notification IDs?
(although I can see the case for keeping them separate as well)...
if the two headers are combined, i would vote that the new combined
Notification-ID is simply returned for NOTIFY responses as well as
callbacks. the possible down side is that if you sent a notification
with an ID, then sent an update for that notification (same ID) and
then the callback came in, you couldnt tell which notification (your
original or the updated) was the source, but really it shouldnt
matter. if you updated the notification, it replaced the original, so
really there was only one notification source."
the GNTP spec says that the encryption key is the first X bytes of the
computehash(keybasis), where X is the key size for the encryption
algorithm:
"To encrypt the message headers or binary data, use the key generated
from the password and salt. Different encryption algorithms require
different key lengths and IV sizes, so use the first X bytes of the
key as required."
since you are using AES, the GNTP spec specifies the following:
AES - key length: 24 bytes (192 bit), block size: 16 byte (128 bit),
iv size: 16 byte (128 bit)
since you need a key length of 24 bytes, you have to use a hashing
algorithm that will generate a value at least that long. that rules
out MD5 and SHA1 in this case, so lets assume you used SHA256.
the key generation process would then be:
Salt: D�iό��r
Salt Bytes: [68, 239, 191, 189, 105, 207, 140, 239, 191, 189, 239,
191, 189, 114]
Salt Hex: 44EFBFBD69CF8CEFBFBDEFBFBD72
Password: testing
Password Bytes: [116, 101, 115, 116, 105, 110, 103]
Key Basis: [116, 101, 115, 116, 105, 110, 103, 68, 239, 191, 189, 105,
207, 140, 239, 191, 189, 239, 191, 189, 114]
Key Basis Hex: 74657374696E6744EFBFBD69CF8CEFBFBDEFBFBD72
Key: [248, 236, 28, 251, 144, 215, 186, 74, 26, 13, 183, 34, 26, 148,
70, 9, 229, 160, 176, 67, 162, 102, 169, 227, 190, 165, 165, 220, 103,
51, 190, 168]
Key Hex: F8EC1CFB90D7BA4A1A0DB7221A944609E5A0B043A266A9E3BEA5A5DC6733BEA8
in this case, you need a 24-byte key, so the actual key would be the
first 24 bytes:
Key: [248, 236, 28, 251, 144, 215, 186, 74, 26, 13, 183, 34, 26, 148,
70, 9, 229, 160, 176, 67, 162, 102, 169, 227]
that is the value you should use for the encryption, as well as the
value that you should hash and send in the GNTP header line as the key
hash. using that approach, GfW should be able to deduce the same key
you used to do the encryption, which (should) allow it to decrypt
properly.
try that out and let me know if it gets you any closer. i can also
update the spec with any input you have that will make it clearer. i
will probably also update the Key Checker page i sent you before to
add the ability to specify the encryption type and have it show the
actual key that should be used (correct size).
i typed that too quickly - although you will only use the first X
bytes of the key, you still have to hash the entire key and send that
value in the GNTP header line. sorry for any confusion.
GfW is expecting that the received encrypted data will be the raw
bytes. i will try to generate a file from GfW that shows what it is
expecting and maybe we can see if it can be decrypted on the mac?
- advertising/browsing via Bonjour using _gntp._tcp
- password manager (not required, but Rudy had mentioned that he
wanted to implement it)
- url callback handling (might already be on the list as part of the
receiving/parsing work yet to be done)
if i think of anything else, i will post them up here.