Beyond 1.2 (GNTP specifically)

7 views
Skip to first unread message

Brian Dunnington

unread,
Oct 2, 2009, 3:04:05 PM10/2/09
to Growl Development
i know you guys want to get your localization process nailed down for
1.2.1, and of course there are always bug fixes as well, but what is
the high-level plan for the next few releases? cutting to the chase,
what i am really asking is how the GNTP stuff is looking and where it
all fits in.

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?)

Peter Hosey

unread,
Oct 2, 2009, 3:14:22 PM10/2/09
to growl-de...@googlegroups.com
On Oct 2, 2009, at 12:04:05, Brian Dunnington wrote:
> 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.

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).

Rudy Richter

unread,
Oct 2, 2009, 3:53:21 PM10/2/09
to Growl Development
did you just volunteer to finish the remaining bits of GNTP? ;)

Brian Dunnington

unread,
Oct 2, 2009, 4:12:36 PM10/2/09
to growl-de...@googlegroups.com
if you want someone who has written exactly zero lines of
Cocoa/Objective-C before to whip it up for you - then sure! =)

Brian Dunnington

unread,
Oct 2, 2009, 4:13:34 PM10/2/09
to growl-de...@googlegroups.com
> 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.

Rudy Richter

unread,
Oct 2, 2009, 4:59:34 PM10/2/09
to Growl Development
sounds like a plan!

in addition to GNTP, we've also got several other things on the table:

Extras Tab & distribution changes
The replacement functionality for the Growl-WithInstaller framework
Sparkle Updating
GrowlTunesPlugin and the subsequent demise of GrowlTunes.app

-rudy

Christopher Forsythe

unread,
Oct 2, 2009, 11:11:45 PM10/2/09
to growl-de...@googlegroups.com
We've got a decent amount of things to work through, gntp is just one of those things. 1.3 is gntp, we want to get localizations figured out, then move on to gntp. I don't want localizations to take forever to figure out a process.

Rudy Richter

unread,
Oct 6, 2009, 11:51:51 PM10/6/09
to Growl Development
evan's bitbucket repo has been merged into growl-development in a gntp
branch, mac to mac works here. unsurprisingly mac to windows and
windows to mac does not work ;)

-rudy

Brian Dunnington

unread,
Oct 7, 2009, 12:21:27 AM10/7/09
to growl-de...@googlegroups.com
> evan's bitbucket repo has been merged into growl-development in a gntp
> branch

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.

Rudy Richter

unread,
Oct 7, 2009, 12:44:47 AM10/7/09
to Growl Development
On Oct 7, 12:21 am, Brian Dunnington <briandunning...@gmail.com>
wrote:
> > evan's bitbucket repo has been merged into growl-development in a gntp
> > branch
>
> 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 athttp://growl.info/hg/growl-development, but i
> am completely new to hg / Mercurial so i need to poke around some
> more.

you found the right place, peter hasn't setup syncing with the GCH
repo yet so everything is still being committed to growl-development.

> > 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).

yup, the first commit i merged was 15 months ago, the last was 11. at
the end of the 7 pages of changesets from evan's bitbucket i was
surprised that the only failure to build was that 2 files hadn't been
added to the GHA target.

if you recall any specific changes to the spec and/or the list of
'remaining stuff' it would probably be beneficial to get all that
documented. that way we've got a complete spec that any of the 4 of us
that has time can work on bringing the code up to snuff (you, me,
peter, or evan).

chris and i are usually in #growl on irc.freenode.net if you've got
real-time questions.

>
> 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.

and with that i go to sleep and dream about the commits i'll make to
cocotron tomorrow ;)

-rudy

Brian Dunnington

unread,
Oct 7, 2009, 11:48:50 AM10/7/09
to growl-de...@googlegroups.com
> if you recall any specific changes to the spec and/or the list of
> 'remaining stuff' it would probably be beneficial to get all that
> documented. that way we've got a complete spec that any of the 4 of us
> that has time can work on bringing the code up to snuff (you, me,
> peter, or evan).

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.

Rudy Richter

unread,
Oct 7, 2009, 10:10:25 PM10/7/09
to Growl Development
On Oct 7, 11:48 am, Brian Dunnington <briandunning...@gmail.com>
wrote:
> > if you recall any specific changes to the spec and/or the list of
> > 'remaining stuff' it would probably be beneficial to get all that
> > documented. that way we've got a complete spec that any of the 4 of us
> > that has time can work on bringing the code up to snuff (you, me,
> > peter, or evan).
>
> 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.

test suite would be useful, even if its windows only (yay vmware). 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.)
gfw does successfully send notifications to the mac, counter to
previous statement of nothing working.

so at this point i'm going to chuck through the code and verify what
actions are missing, whether there are any missing required headers
for those options, whether its currently ignoring any of the optional
ones. and just generally get all those spec defined headers at least
checked for if not handled by the code.

it also doesn't look like the spec makes any mention to Data-, just
X-.

Rudy Richter

unread,
Oct 8, 2009, 12:36:31 AM10/8/09
to Growl Development
I've got growl sending back a response to the subscribe request, gfw
says "(offline) server unavailable", what am i missing?

"GNTP/1.0 -OK NONE NONE
Response-Action: SUBSCRIBE
Subscription-TTL: 300

GNTP/1.0 END

"

On Oct 7, 11:48 am, Brian Dunnington <briandunning...@gmail.com>
wrote:
> > if you recall any specific changes to the spec and/or the list of
> > 'remaining stuff' it would probably be beneficial to get all that
> > documented. that way we've got a complete spec that any of the 4 of us
> > that has time can work on bringing the code up to snuff (you, me,
> > peter, or evan).
>
> 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

Brian Dunnington

unread,
Oct 8, 2009, 10:09:56 AM10/8/09
to growl-de...@googlegroups.com
> I've got growl sending back a response to the subscribe request, gfw
> says "(offline) server unavailable", what am i missing?
>
> "GNTP/1.0 -OK NONE NONE
> Response-Action: SUBSCRIBE
> Subscription-TTL: 300
>
> GNTP/1.0 END
>
> "

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

Brian Dunnington

unread,
Oct 8, 2009, 10:24:46 AM10/8/09
to growl-de...@googlegroups.com
> test suite would be useful, even if its windows only (yay vmware).

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.

Brian Dunnington

unread,
Oct 8, 2009, 10:34:34 AM10/8/09
to growl-de...@googlegroups.com
> to hopefully make is simpler, i am attaching the raw tests for you to
> use.

it would help if i actually attached the file...

tests.zip

Rudy Richter

unread,
Oct 8, 2009, 12:11:22 PM10/8/09
to Growl Development
At this point i plan on including the keep-alive and close connection
types in the implementation, what was there previously blanked tagged
every request with GNTP/1.0 END.

On Oct 8, 10:09 am, Brian Dunnington <briandunning...@gmail.com>
wrote:

Rudy Richter

unread,
Oct 9, 2009, 12:29:22 AM10/9/09
to Growl Development
I turned off the password on the subscription for the time being

where is it putting \r\n in this block then?

i just compiled gfw, and it seems to be receiving "GNTP/1.0 -OK NONE\r
\n" in ConnectorBase.cs' ReadCallback() on string response =
System.Text.Encoding.UTF8.GetString(state.Buffer, 0, length);

should it not be getting the full message there?

let me know if i'm looking in the wrong place

-rudy

On Oct 8, 10:09 am, Brian Dunnington <briandunning...@gmail.com>
wrote:

Rudy Richter

unread,
Oct 9, 2009, 12:49:32 AM10/9/09
to Growl Development
looks like its an issue with how we were writing the data to the
asyncsocket in our outgoing packet, we were writing each header part
out separately.

it would write the first line, then each of the subsequent lines, gfw
was receiving only the first line and deciding it was an invalid
response and bailing on the rest of it.

if i concatenate all the data together into a single data blob and
send that, gfw correctly sees the subscription and displays the
IP:Port and TTL in the GUI.

so its at least formatted correctly and gfw recognizes the response
now.

-rudy

Mike Chambers

unread,
Oct 9, 2009, 12:48:23 AM10/9/09
to growl-de...@googlegroups.com
fyi, I have / had created an ActionScript 3 library that worked with
the implementation put together about a year ago.

You can find it here:

http://code.google.com/p/as3growl/

It might be useful for some testing, or to see what was working then.

mike chambers

mikech...@gmail.com

Evan Schoenberg, M.D.

unread,
Oct 9, 2009, 1:30:51 AM10/9/09
to growl-de...@googlegroups.com
That sounds like a gfw bug at first glance... Streaming data can
arrive with any latency as long as the stream isn't closed (within a
timeout, if one is defined, and gntp doesn't specify one afaik).

-Evan

Rudy Richter

unread,
Oct 9, 2009, 10:07:48 AM10/9/09
to Growl Development
Indeed, looking at the gfw code it definitely looks like its
incorrectly assuming all the data is in a single packet rather than
attempting to validate them as they are received.

-rudy

On Oct 9, 1:30 am, "Evan Schoenberg, M.D." <eva...@dreskin.net> wrote:
> That sounds like a gfw bug at first glance... Streaming data can  
> arrive with any latency as long as the stream isn't closed (within a  
> timeout, if one is defined, and gntp doesn't specify one afaik).
>
> -Evan
>

Brian Dunnington

unread,
Oct 9, 2009, 1:01:08 PM10/9/09
to growl-de...@googlegroups.com
i dont see which part you are referring to - GfW assumes the stream
can come in with any latency. it does read the stream as it comes in,
but does not assume it will all come as one chunk. in other words, if
the first line comes in with something wrong, GfW will stop reading
once it finds an error. otherwise, it will continue to read the stream
indefinitely until the end of the message is received.

if you are running GfW, you can enable some logging that shows what is
received/sent. here are some long-winded instructions: how to enable
logging - http://groups.google.com/group/growl-for-windows/browse_thread/thread/1c17687b801efff0/038d1645921177c3?hl=en&lnk=gst&q=logging#038d1645921177c3
- but you can also just launch the app with the following parameters
which does the same thing:

growl.exe /log:true

wait - before i go any farther...i am referring to receiving REGISTER
and NOTIFY requests. this is specific to SUBSCRIBE responses, which
essentially flip-flops the sender/receiver. i will take a look and see
what i can find. do you know if REGISTER and NOTIFY requests are
working OK? there are lots of libraries using those commands and i
have not had any issues with them so far.

i will report back what i find - thanks for the pointers on where to look.

Rudy Richter

unread,
Oct 9, 2009, 1:10:56 PM10/9/09
to Growl Development
i haven't looked at register or notify yet.

this was in attempting to get gfw to confirm correct receipt of
subscription requests and reflect correct parsing in the GUI.

the code as i read it in gfw reads off the socket (which in this case
would be "GNTP/1.0 -OK NONE\r\n") and then attempts to parse that
string as the entirety of the response, whereas growl has written out
two more chunks representing the next two headers. gfw throws an
exception saying there's a missing header (either the ttl or the
response-action) and rejects the response. at least as of trunk in
your google code repo.

i ended up just compiling gfw and watching the data as it came in to
see what gfw was doing.

-rudy

On Oct 9, 1:01 pm, Brian Dunnington <briandunning...@gmail.com> wrote:
> i dont see which part you are referring to - GfW assumes the stream
> can come in with any latency. it does read the stream as it comes in,
> but does not assume it will all come as one chunk. in other words, if
> the first line comes in with something wrong, GfW will stop reading
> once it finds an error. otherwise, it will continue to read the stream
> indefinitely until the end of the message is received.
>
> if you are running GfW, you can enable some logging that shows what is
> received/sent. here are some long-winded instructions: how to enable
> logging -http://groups.google.com/group/growl-for-windows/browse_thread/thread...

Brian Dunnington

unread,
Oct 9, 2009, 3:25:03 PM10/9/09
to growl-de...@googlegroups.com
> this was in attempting to get gfw to confirm correct receipt of
> subscription requests and reflect correct parsing in the GUI.
>
> the code as i read it in gfw reads off the socket (which in this case
> would be "GNTP/1.0 -OK NONE\r\n") and then attempts to parse that
> string as the entirety of the response, whereas growl has written out
> two more chunks representing the next two headers.  gfw throws an
> exception saying there's a missing header (either the ttl or the
> response-action) and rejects the response. at least as of trunk in
> your google code repo.
>
> i ended up just compiling gfw and watching the data as it came in to
> see what gfw was doing.

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).

Rudy Richter

unread,
Oct 9, 2009, 4:53:32 PM10/9/09
to Growl Development
will do, i'll flip it back to the previous way and see what happens.

-rudy

Rudy Richter

unread,
Oct 10, 2009, 12:40:13 PM10/10/09
to Growl Development
updated to r92,

doesn't look like it fixes that behavior. the code hits state.Delegate
(response), that throws an exception when the delegate parses out the
string and the code still bails out. looks like response should have
the result of the subsequent async socket reads appended to it rather
than appending that initial response into state?

-rudy

Brian Dunnington

unread,
Oct 10, 2009, 9:32:38 PM10/10/09
to growl-de...@googlegroups.com
ok, it should be fixed for real this time. i created a test server
that sent chunked responses so i could test the behavior before
committing it this time. now it will read until it finds that actual
end of the message, even if the data arrives in pieces. the changes
are in r93 if you want to try them out.

Rudy Richter

unread,
Oct 11, 2009, 11:43:21 AM10/11/09
to Growl Development
yup, that seems to be working fine now.

it looks like its sending TTL renewals in batches?
got one at 11:35:54.497 which Growl responded to at 11:35:54.503, it
then received another request at 11:36:06.261 which it got a reply to
at 11:36:06.269. Its not consistent though, the next one I got was
11:40:03.870 and that was the only one received.

I started implementing the password hashing algorithms, I started with
md5, but the values at the various stages of calculation don't match
in growl vs what gfw calculates. not sure where the disconnect is
yet.

On Oct 10, 9:32 pm, Brian Dunnington <briandunning...@gmail.com>
wrote:

Brian Dunnington

unread,
Oct 11, 2009, 11:47:20 AM10/11/09
to growl-de...@googlegroups.com
i will have a look at the TTL renewal messages to see if i can figure
out why they came in like that. glad it is at least working now
though.

as for the password hashing, this page might be useful:
http://www.growlforwindows.com/gfw/help/keychecker.aspx

it lets you input a password and salt and then shows the
hash/encryption outputs at each step of the process. it is a quick way
to see where the values diverge.

Rudy Richter

unread,
Oct 11, 2009, 12:34:04 PM10/11/09
to Growl Development
cool, md5 hashing of the password works, time to clean up the code and
implement the other hashing algorithms.

-rudy

On Oct 11, 11:47 am, Brian Dunnington <briandunning...@gmail.com>
wrote:

Rudy Richter

unread,
Oct 11, 2009, 1:28:27 PM10/11/09
to Growl Development
all the hashing algorithms are confirmed working with growl sending
messages to gfw, will implement going the other way after i've got
encryption working

-rudy

Rudy Richter

unread,
Oct 11, 2009, 3:44:21 PM10/11/09
to Growl Development
hrm, does Growl for Windows not support coalescing of notifications?

as part of my trip through the GNTP code evan wrote i went through and
replaced each direct string reference with a global one (change one
and change 'em all), it looks like we've got some additional headers
defined that aren't in the spec you've got posted.

Notification-Coalescing-ID (this one is definitely so that an app can
send multiple messages and if its still on screen it can stay on
screen and have its data replaced with the new notificaiton's data)

Notification-Callback-Target-Method (this one seems to support GET and
POST values)

-rudy

Brian Dunnington

unread,
Oct 11, 2009, 5:56:30 PM10/11/09
to growl-de...@googlegroups.com


>
> hrm, does Growl for Windows not support coalescing of notifications?
>
> as part of my trip through the GNTP code evan wrote i went through and
> replaced each direct string reference with a global one (change one
> and change 'em all), it looks like we've got some additional headers
> defined that aren't in the spec you've got posted.
>
> Notification-Coalescing-ID (this one is definitely so that an app can
> send multiple messages and if its still on screen it can stay on
> screen and have its data replaced with the new notificaiton's data)

GfW supports the Notification-Coalescing-ID header but currently
doesn't do anything with it (notifications are treated as new- I just
haven't had the time to implement it properly yet)

>
> Notification-Callback-Target-Method (this one seems to support GET and
> POST values

This was dropped- there is no way to launch a browser and specify POST
data, so only GET is allowed. As such, the header is not needed (there
are some posts in this group somewhere discussing it- I will try to
dig them up when I am back at my computer)

Brian Dunnington

unread,
Oct 11, 2009, 10:34:07 PM10/11/09
to growl-de...@googlegroups.com
>>
>> hrm, does Growl for Windows not support coalescing of notifications?
>>
>> as part of my trip through the GNTP code evan wrote i went through and
>> replaced each direct string reference with a global one (change one
>> and change 'em all), it looks like we've got some additional headers
>> defined that aren't in the spec you've got posted.
>>
>> Notification-Coalescing-ID (this one is definitely so that an app can
>> send multiple messages and if its still on screen it can stay on
>> screen and have its data replaced with the new notificaiton's data)
>
> GfW supports the Notification-Coalescing-ID header but currently doesn't do
> anything with it (notifications are treated as new- I just haven't had the
> time to implement it properly yet)

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?

Brian Dunnington

unread,
Oct 12, 2009, 2:47:28 PM10/12/09
to growl-de...@googlegroups.com
> 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."

Rudy Richter

unread,
Oct 13, 2009, 5:16:37 PM10/13/09
to Growl Development
does it make sense to have the second notification pass the
notification-id of the previous notification id as its notification-
coalescing-id as a mechanism for not having to specify it initially
but allow subsequent notifications to direct the process to do
coalescing? i wasn't really paying too much attention to the list when
all of the GNTP spec was hashed out, but that seems like an answer to
#2, and might address the question of which notification the user
interacted with (it would still just be the Notification-ID).

On Oct 12, 2:47 pm, Brian Dunnington <briandunning...@gmail.com>
wrote:

Rudy Richter

unread,
Oct 13, 2009, 5:19:14 PM10/13/09
to Growl Development
i made it decently far with AES encryption last night, I'm not 100%
sure where the breakdown is in my code yet. I'm going to implement
the corresponding decryption method and see if it actually decrypts
properly on the mac. right now gfw throws a decryption exception that
mentions something about padding and not being able to remove it.

-rudy

Brian Dunnington

unread,
Oct 13, 2009, 5:20:15 PM10/13/09
to growl-de...@googlegroups.com
that makes sense to me; i just wasnt sure then if developers might get
confused if they had to pass different values for Notification-ID
(some new unique value) and Notification-Coalescing-ID (the old
Notification-ID value) and that is why i suggested just using the
Notification-ID for everything. i was just thinking out load though,
and there might be a very good reason to keep the two distinct values.

even if we keep the two distinct headers, i think your idea of using
N-C-ID to override a previous N-ID makes the most sense.

Brian Dunnington

unread,
Oct 13, 2009, 5:24:13 PM10/13/09
to growl-de...@googlegroups.com
make sure you are using the PKCS5 (PKCS7) padding scheme. otherwise,
if you want to post up your inputs (request, password, salt, IV), we
can run it through both systems to maybe see where the discrepancy is.
i have used AES from Flash and PHP to send encrypted GNTP messages, so
it *should* be cross-platform at this point, but the encryption always
seems to be tricky to get just right from each language i have tried
so far.

Rudy Richter

unread,
Oct 13, 2009, 6:25:31 PM10/13/09
to Growl Development
i'll be on #growl on freenode when i get home from work.

I definitely had pkcs7 (the only padding option available) turned on,
and i confirmed that IV was of the proper length, the key length was
set to 192bit. I don't think the api actually provided a mechanism
for providing salt, so will have to double check that.

I'm going to make sure that it correctly decrypts what was encrypted
as well, since its going to need it anyway, and should serve as at
least one way to determine if something is actually fubar with the
code (if it can't decrypt what it just encrypted, something is clearly
not right :)

-rudy

On Oct 13, 5:24 pm, Brian Dunnington <briandunning...@gmail.com>
wrote:

Brian Dunnington

unread,
Oct 13, 2009, 6:31:10 PM10/13/09
to growl-de...@googlegroups.com
ok. i have some things i have to get done this evening, but i will try
to check on #growl every now and then to see if i can catch you.

it sounds like everything was set up correctly, so nothing is coming
to mind immediately. (the salt is only used in combination with the
password to generate the key). make sure you use the generated key to
encrypt, not the key basis or key hash. if i can think of anything
else, i will let you know.

Brian Dunnington

unread,
Oct 14, 2009, 1:10:25 AM10/14/09
to growl-de...@googlegroups.com
sorry i didnt get back to #growl in time to catch you again, but i did
see your messages.

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).

Brian Dunnington

unread,
Oct 14, 2009, 2:32:44 AM10/14/09
to growl-de...@googlegroups.com
> ...as well as the value that you should hash and send in the

> GNTP header line as the key hash.

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.

Rudy Richter

unread,
Oct 14, 2009, 10:05:56 AM10/14/09
to Growl Development
I can try stepping it back to SHA256, and see. I had been doing AES
w/ SHA512 for the key hashing.

I inspected the values that get set in Key.cs when keyHash ==
actualKeyHash and they all match up with the values that Growl is
working with, and the block of encrypted bytes also matches what's
being sent to gfw.

oddly if i switch to DES or 3DES it just claims "bad data" as the
exception it throws when it tries to decrypt it.

-rudy

On Oct 14, 1:10 am, Brian Dunnington <briandunning...@gmail.com>
wrote:

Brian Dunnington

unread,
Oct 14, 2009, 10:17:00 AM10/14/09
to growl-de...@googlegroups.com
SHA256 or SHA512 shouldnt matter, as long as you are using the first
24 bytes of the key. if GfW is ending up with the same values then i
am not sure what could be going on.

can you post up a sample encrypted request along with the values used
(password, salt, iv) and also the unencrypted request for comparison?

Christopher Forsythe

unread,
Oct 14, 2009, 10:22:33 AM10/14/09
to growl-de...@googlegroups.com
Maybe instead of the first 24 bytes, you could look for something like ENDENCRYPTION (bad example probably)? Just a thought if backing down to 256 does work.

Brian Dunnington

unread,
Oct 14, 2009, 11:02:27 AM10/14/09
to growl-de...@googlegroups.com
Rudy - i am wondering if it is an encoding issue? are you sending the
raw bytes that are the result of the encryption routine, or are you
converting the output to something else (like UTF8 or possibly hex
encoding the values or something) before sending?

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?

Rudy Richter

unread,
Oct 14, 2009, 11:22:39 AM10/14/09
to Growl Development
should be the raw bytes, i'm taking the output of the encryption
operation and stuffing it into the NSData object that ultimately gets
written to the socket.

password: testing
hashing algorithm: SHA256
key bytes:
6fe449f104477663304693cff6453bc5f5e6992dacb822de3e62fe0448ade1de
key hash:
fe3951bc61b60f3ad4deb2e61d470c06d07bed9d366dc9540b2f0429b6866815
salt: bbdf0d5db70ab6f0bf6a18b804a4c3c0

encryption algorithm: 3DES
iv: af88602d2e17c145

encrypted payload:
18b337f2e8bd00254c395e358d1cd619889bd374eb48d3e74cc1c4137ddb5dc1e23d914b5a529462e9c9cb990ac38aa771ed825c172f5981f3fed7ec54a9f9cfa65bc590c0bbf58cf3e32fdda14fe568cab913f0bca3b833a34083b0093f6ac611ea1e15763d8a6d028f62cb15ebb98321316ce7578a14376fc4c4167a3d2c46838b146810d334d5578dbffa25cf3d44bb333e978afc70b4cf9367c0a5201facca5fa5a241858dde7e973dae17d0f5ef9c7fba0c752d6a935d06ecfa641e798f3ec5e6d68c4ecc8b4dc511cf431d5beef37cb2c4457a7ff1e6bc5913fbb75a67a75c483f43093302c05f5443c15fef78cea1f8efd14ac7d3a666ee60b4a17f143a4647e0aa1d7169872e34fe2b3af7bdc0f2fac5532a499ad4512b44497d67cc4b0fb0038cc0f72a153ec34e6d165b6dc46b783f5450aebc08bce0b3be9e515afd3a9022a2214ab2ceb70a2f6c8219d2741eda9e7cc4e0dffe3f7f7303491c97965127f45d24c13c3a5c03f7db3c34ab1f4b34b6fe24435e0ccfc299ee055d938596d805a70e9af10c133735cf077660412ec23673d64d283835003b6c07dadac74db61e76437b22235aa9803450c833ee422b2e5beb6754923e8bcbd9f5c6a1d8942784a62b651881ca11770080331030acb6a66a38a3e5afc37cb7c946a84f19bc90fd6cf5cd7ad95771dadc3e5dbd3e6908dc85739c774176884c2f030cad7c817769607401c9f752cad3582160eab41f216e3cb3d519576366aa1c9bce342954641281c5133826113c556f7179c2a07b284481acedf1085f7f9768fd74ee854b6c04ba04566187699f81e351e528323d50e439d0d168ecfb1500f9ef8b8f8018220f2814948940a5fda118d44ad1dc7c58c66dfbc81c66f3f229b8c57dbd30c789c8d98c2c0117140e431369c37fa23d77c8d92bfcd4fa42db3c5f86f30cba4e198a786d4591

decrypted message block (this is what I get out of the other end if i
run the encrypted data through the corresponding decrypt method
passing in the same values for the iv, and encryptionKey as are
specified above):

Application-Name: Growl
Application-Icon: x-growl-resource://1aa5ef7f6ff637cd70b4d35463889f8e
X-Application-BundleID: com.Growl.GrowlHelperApp
Notifications-Count: 3
Sent-By: zoidberg
Origin-Machine-Name: zoidberg
Origin-Software-Name: Growl
Origin-Software-Version: 1.2
Origin-Platform-Name: Mac OS X
Origin-Platform-Version: 10.6.1

Notification-Name: Growl update available
Notification-Display-Name: Growl update available
Notification-Enabled: Yes

Notification-Name: User went idle
Notification-Display-Name: User went idle
Notification-Enabled: no

Notification-Name: User returned
Notification-Display-Name: User returned
Notification-Enabled: no


log file from gfw:
Timestamp: 10/14/2009 10:08:30 AM


-----------------------------------------------------

GNTP/1.0 REGISTER 3DES:af88602d2e17c145
SHA256:fe3951bc61b60f3ad4deb2e61d470c06d07bed9d366dc9540b2f0429b6866815.bbdf0d5db70ab6f0bf6a18b804a4c3c0
�7�� %L9^5� � ���t�H��L�� }�]��=�KZR�b��˙
Ê�q�\ /Y�����T��Ϧ[Ő������/ݡO�hʹ 𼣸3�@�� ?j� � v=�m �b� 빃!
1l�W� 7o�� z=,F�� h �4�W���%�=D�3>���p�ϓg�� ��_��A���~�=� ��� � u-j�]
��d y�>��֌N̋M� �C [��|��Ez ��Y ��Zg�\H?C
3 �_TC�_�xΡ���J�Ӧf�`�� :FG� qi�.4�+:������S*I��Q+DI}g�K � ���* >�Nm
[m�kx?TP�� �೾�QZ�:�"�!J�η
/l� �t ڞ|����? s I ��Q'�]$�<:\ ��<4� K4��$C^ �™� ]���� � ��
75� v`A.�6s�M(85 ;l ���M� vC{"#Z��4P�3�B+.[�gT�>����ơؔ'��+e �� w
�3 0���j8���|��F�O ���l��z�Wq��>]�>i ܅s�wAv�L/ �|�wi`t ��R��X!`� !
n<�� Wcf� ��4)Td �� 8& <Uoqy {(D���� _ �h�t�Kl � Va�i���Q�(2=P�9��h��
�� " ( ��@��� �J��|X�m�� f��)��}�0lj�ٌ, C i� �=w��+���B�<_��
�N �xmE�

<Additional request data may not have been read after the message was
invalidated.>

-----------------------------------------------------

GNTP/1.0 -ERROR NONE
Error-Code: 300
Error-Description: Malformed request (Decrypt: CryptographicException
- Bad Data.
)
Origin-Machine-Name: RUDY-8409FF6C63
Origin-Software-Name: Growl/Win
Origin-Software-Version: 2.0.0.0
Origin-Platform-Name: Microsoft Windows NT 5.1.2600 Service Pack 3
Origin-Platform-Version: 5.1.2600.196608
X-Message-Daemon: Growl/Win
X-Timestamp: 10/14/2009 10:08:30 AM

-rudy

On Oct 14, 11:02 am, Brian Dunnington <briandunning...@gmail.com>
wrote:

Brian Dunnington

unread,
Oct 14, 2009, 12:41:34 PM10/14/09
to growl-de...@googlegroups.com
when i encrypt it (in C# via GfW), i get a different result. it is
still 680 bytes long, but totally different bytes.

as a test, you can go to http://crypto.hurlant.com/demo/ and try some
online encrypting using the as3crypto library for comparison. if you
use the 'Secret Key' tab and the following values, it will decrypt ok:

3DES, CBC, PCKS#5

Key Format: Hex
Key: 6fe449f104477663304693cff6453bc5f5e6992dacb822de3e62fe0448ade1de

Cipher Text: Hex
54A89F59A3AD08D8B232ED0EA4D327B5454EE3052AC2832F4383B9D5F4CD49F7A61CA252637EB97CE2AEBB0BC6CD57A0ACE33DCDCDAD17C59B9D54F11DB5289E2C17F29EBBC2034BC7C3D71DB4246462BA4E7BC54B746FB233F89EE4C2B2B0242E38C5F1C9F04F25E1DC3FFD53CB5031FA81CC643485DF72A7A5EBCDE72C7A12D01CAAD47D1252DFDA2136A74E135A775E8CCFDFEAD26E9819495EF6817965EF0106BB89F7AD6A53B185C00C4F67105337EFF538416924F87EFFBBBD9818DB5B795B10C71AC8DFEB8D0753CC8C3F9C4025D671FE70B6344F00A3EDDE5E4959A39A4E007C442E4A6AA57300A1CB667872264E0A7E81561A3B659FA12424C673B42F86E9BE1A01D5A5F2AB7B16C2287B57C4634F307020EE77A05438E8C23B7ACCA1F6D6C7DDC358C490E197A1BE0C284B409AC6CBB719B812B77AECAE02D705C37222FCD476AEE3362E6A82CC366022E5911678D1DD3D1AEB048425EE4084BDC7ED974A781AE1793248F3AEB9B63121298F3FBD23E1321DE725D45982A19BBE8A846FDF57D0EA379A8DAF9C51EE21A5BC1A78C0ACB316F93876B4B627E3F5584268412B19F87BF928ED4464991FFDC93B27BB036DFDFBE1F8F579DA70AFA70FE55908E516D8B9A1B6A186D46F6E584A3B6386332E4705184C00CFAF449D322C7AE942AF4BFA1FE93E9ACB340E637706083E563F7D6CB937BC1C815DC4E77C854A018F8531FB71DBCB1E4536016B9DCD7D3B713C18292650E49C8EAB8DBF7432EA8B42D8A92CAC806D425BFD98844F2B4745426F68F6D1E4430A3646A25F67995C628B0CFF3961B0D8551B7DC2C0416756D57E6845F1E4347F2DD06530B174DB78D14D2A0B5AF56F54A45561CE1386FD4D1F2D1D6C3F4D38EAF5B7A15AE20AB679F258284C826BFD3718F164ACE2FBAFD013E9CCF31B97429180134FE19EDE9239BF49E62FC6D0331D

IV: af88602d2e17c145

however, if you change the cipher text to the following value, it no
longer is able to decrypt:

18b337f2e8bd00254c395e358d1cd619889bd374eb48d3e74cc1c4137ddb5dc1e23d914b5a529462e9c9cb990ac38aa771ed825c172f5981f3fed7ec54a9f9cfa65bc590c0bbf58cf3e32fdda14fe568cab913f0bca3b833a34083b0093f6ac611ea1e15763d8a6d028f62cb15ebb98321316ce7578a14376fc4c4167a3d2c46838b146810d334d5578dbffa25cf3d44bb333e978afc70b4cf9367c0a5201facca5fa5a241858dde7e973dae17d0f5ef9c7fba0c752d6a935d06ecfa641e798f3ec5e6d68c4ecc8b4dc511cf431d5beef37cb2c4457a7ff1e6bc5913fbb75a67a75c483f43093302c05f5443c15fef78cea1f8efd14ac7d3a666ee60b4a17f143a4647e0aa1d7169872e34fe2b3af7bdc0f2fac5532a499ad4512b44497d67cc4b0fb0038cc0f72a153ec34e6d165b6dc46b783f5450aebc08bce0b3be9e515afd3a9022a2214ab2ceb70a2f6c8219d2741eda9e7cc4e0dffe3f7f7303491c97965127f45d24c13c3a5c03f7db3c34ab1f4b34b6fe24435e0ccfc299ee055d938596d805a70e9af10c133735cf077660412ec23673d64d283835003b6c07dadac74db61e76437b22235aa9803450c833ee422b2e5beb6754923e8bcbd9f5c6a1d8942784a62b651881ca11770080331030acb6a66a38a3e5afc37cb7c946a84f19bc90fd6cf5cd7ad95771dadc3e5dbd3e6908dc85739c774176884c2f030cad7c817769607401c9f752cad3582160eab41f216e3cb3d519576366aa1c9bce342954641281c5133826113c556f7179c2a07b284481acedf1085f7f9768fd74ee854b6c04ba04566187699f81e351e528323d50e439d0d168ecfb1500f9ef8b8f8018220f2814948940a5fda118d44ad1dc7c58c66dfbc81c66f3f229b8c57dbd30c789c8d98c2c0117140e431369c37fa23d77c8d92bfcd4fa42db3c5f86f30cba4e198a786d4591

i am still not sure where the problem is arising from, but it appears
that the encrypted result is invalid somehow. you said that you were
able to decrypt it again though, so that would point to a setting
somewhere that is consistent when you encrypt/decrypt using the same
library, but not the same when using these other libraries.

i just had one other thought - some crypto libraries embed the IV into
the encrypted result, so maybe that is happening? since we are both
ending up with 680 bytes, that doesnt sound like the issue, but maybe
something to check.

Rudy Richter

unread,
Oct 17, 2009, 1:22:10 AM10/17/09
to Growl Development
so i decided to wait a day or so, not work on it to clear my brain. I
leveled most of the implementation and started over. the result was
that i had hashing and encryption with all the valid combinations
working in about 10 minutes, heh. So I can now send encrypted
messages to growl for windows, I haven't tried going the other way
yet. It doesn't currently do any error handling, or restriction of
hashing and encryption algorithm combinations, so i'm going to run
back through and clean all the code up.

the first couple times i ran through it I had to do a double take on
the gfw log file because it was still encrypted there.

so when that's completed the remainder:
forwarding on any Data- headers, making sure it properly encrypts
binary chunks separately from the header and that growl for windows
doesn't balk at them, socket reuse, and making sure Growl can receive
encrypted transmissions from gfw.

-rudy

On Oct 14, 12:41 pm, Brian Dunnington <briandunning...@gmail.com>
wrote:
> when i encrypt it (in C# via GfW), i get a different result. it is
> still 680 bytes long, but totally different bytes.
>
> as a test, you can go tohttp://crypto.hurlant.com/demo/and try some

Brian Dunnington

unread,
Oct 27, 2009, 4:24:35 PM10/27/09
to growl-de...@googlegroups.com
Chris asked on #growl was else was left to do and i just remembered a
few outlying things that i didnt want to forget, so i am posting them
up here:

- 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.

Reply all
Reply to author
Forward
0 new messages