New user - comments (and patches) to 0.4.6-1

Stephan Dahl <sdahl-yrwVVJnAJyJ/[email protected]>
Newsgroups gmane.network.instant-messaging.ayttm.user
Message-ID <[email protected]>
Hi,

I've recently started using Ayttm (my friends insist on using MSN, and I 
won't install Windows :-).

It's a great piece of work, but I did have a few snags to work out out - 
and I've added a few features I found useful.  Here's my change log, 
with patches, in case someone else finds them useful.

To the dev team: Do you have a more formal process for submitting 
patches than this mailing list?

---


Changelog to Ayttm

Base version: Ayttm 0.4.6-1

Summary
-------

1. Removed pop-up for unloaded modules
2. Added support for multiple SSL certificates per server
3. Changed status dialog title to show number of connected contacts
4. Fixed image_2_jpc undefined symbol
5. Bug in configure's detection of artsc
6. Changed format of contact on/offline message to include timestamp


Change motivation and description
---------------------------------

1. Removed pop-up for unloaded modules

I kept getting a popup on startup with the text:

Plugin /usr/local/lib/ayttm/yahoo2.la has not been loaded because of an 
error:
/usr/local/lib/ayttm/yahoo2.so: undefined symbol: image_2_jpc

I don't use yahoo, so I could care less - but I still had to click
on the #%? popup, which was modal and quickly buried in other frames.
The only possible response is OK, so it's really just noise. I removed 
the popup and redirected the text to stderr.

Patch#1: Change to:
src/plugin.c


2. Added support for multiple SSL certificates per server

The messenger.hotmail.com server kept switching SSL certificate on me -
I suspect that it is really two servers behind a load balancer.

I changed the implementation of the SSL certificate store (in
$HOME/.ayttm/certs) to support any number of stored certificates
for a specified server/port combination. If any of the certs match,
the connection is quietly accepted. Of course, all certs must be
explicitly approved by the user.

Also added a popup warning when a new, signed certificate is presented,
noting that the signature is valid - before, any signed certificate was
quietly accepted.

Patch#2: Change to:
src/ssl_certificate.c
src/ssl_certificate.h



3. Changed status dialog title to show number of connected contacts

I have disabled sound for ayttm (it won't work for me - I'll look into
it later), and keep the status window on another desktop or minimized.
Thus, I'd like to get more information from the panel where all the
application titles are shown - "Ayttm 0.4.6-1" is really void of meaning
after the first few days :->. I changed it to show number of online
contacts. This is more useful, IMO.

Also tweaked the duration of the title change when a contact goes on-
or offline from 5 to 10 seconds. I don't glance there often, and I like
my desktop quiet.

Patch#3: Change to:
src/status.c


4. Fixed image_2_jpc undefined symbol

Same as 0.4.6-11 - I got a Yahoo account just for kicks, and wanted to 
see if I could get it to work.
src/image_window.c: Moved definitions outside #ifdef
Kind of obsoletes change #1, but I still think that popup was annoying.

Patch#4: Change to:
src/image_window.c


5. Bug in configure's detection of artsc

The configure script did not detect aRTs support - so I had to manually
change config.h to #define ARTS_SOUND (and, after some hassle, #define
ARTS_FREE_IS_BROKEN as well).

Also had to change src/Makefile to include
EB_CFLAGS = ... -I/opt/kde2/include/artsc
EB_LIBS = ... -L/opt/kde2/lib -lartsc

I don't have the patience today to debug the configure script, so no patch.


6. Changed format of contact on/offline message to include timestamp

Added a timestamp to the contact online/offline status message at the
bottom of the status window. Had to remove code in status.c which
disables messages with digits in them - unknown why, but it hasn't
blown up yet...

Included in patch#3



Hope you like it,
-- 
Stephan (sdahl-yrwVVJnAJyJ/[email protected])
To be is to do.
		-- I. Kant
To do is to be.
		-- A. Sartre
Yabba-Dabba-Doo!
		-- F. Flinstone
ayttmdiff1.txt (text/plain, 597 B)
Index: plugin.c
===================================================================
RCS file: /home/cvsroot/ayttm/src/plugin.c,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 plugin.c
157c157
< 		snprintf(buff, 512, _("Plugin %s has not been loaded because of an error:\n\n%s"),
---
> 		snprintf(buff, 512, _("Plugin %s has not been loaded because of an error:\n\n%s\n"),
159c159,161
< 		ay_do_error( _("Plugin error"), buff );
---
> 		fprintf(stderr,buff); 
> 		/* Since we're not doing anything about it anyway, we don't want the blocking popup */
> 		/* ay_do_error( _("Plugin error"), buff ); */
ayttmdiff2.txt (text/plain, 10.1 KB)
Index: ssl_certificate.c
===================================================================
RCS file: /home/cvsroot/ayttm/src/ssl_certificate.c,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 ssl_certificate.c
37a38
> #include <dirent.h>
40c41,43
< static SSLCertificate *ssl_certificate_new_lookup(X509 *x509_cert, char *host, int port, int lookup);
---
> char *scandir_prefix;
> 
> static SSLCertificate *ssl_certificate_new_lookup(X509 **x509_cert, int certs, char *host, int port, int lookup);
80c83,84
< 	return ssl_certificate_new_lookup(x509_cert, host, port, TRUE);
---
>     X509 *cert[1] = {x509_cert};
>     return ssl_certificate_new_lookup(cert, 1, host, port, TRUE);
83c87
< static SSLCertificate *ssl_certificate_new_lookup(X509 *x509_cert, char *host, int port, int lookup)
---
> static SSLCertificate *ssl_certificate_new_lookup(X509 **x509_cert, int certs, char *host, int port, int lookup)
84a89,90
>         int i;
> 	
91c97,101
< 	cert->x509_cert = X509_dup(x509_cert);
---
> 	cert->certs = certs;
> 	cert->x509_cert = malloc(sizeof(x509_cert)*certs);
> 	for (i=0; i<certs; i++) {
> 	    cert->x509_cert[i] = X509_dup(x509_cert[i]);
> 	}
99a110,123
> static void ssl_certificate_append(X509 *new, SSLCertificate *exist) 
> {
>     int i;
>     X509 **certs = malloc(sizeof(new)*(exist->certs+1));
> 
>     for (i=0; i<exist->certs; i++) {
> 	certs[i]=exist->x509_cert[i];
>     }
>     certs[exist->certs]=X509_dup(new);
>     exist->certs+=1;
>     free(exist->x509_cert);
>     exist->x509_cert = certs;
> }
> 
117a142,143
> 	int i;
> 	char *certno;
127,134c153,164
< 	port = g_strdup_printf("%d", cert->port);
< 	file = g_strconcat(config_dir, G_DIR_SEPARATOR_S, 
< 			  "certs", G_DIR_SEPARATOR_S,
< 			  cert->host, ".", port, ".cert", NULL);
< 
< 	g_free(port);
< 	fp = fopen(file, "wb");
< 	if (fp == NULL) {
---
> 	for (i=0; i<cert->certs; i++) {
> 	    certno = g_strdup_printf("%d",i+1);
> 	    port = g_strdup_printf("%d", cert->port);
> 	    file = g_strconcat(config_dir, G_DIR_SEPARATOR_S, 
> 			       "certs", G_DIR_SEPARATOR_S,
> 			       cert->host, ".", port, ".", certno, ".cert", NULL);
> 
> 	    g_free(certno);
> 	    g_free(port);
> 	    fp = fopen(file, "wb");
> 	    if (fp == NULL) {
> 		fprintf(stderr,"Error writing file '%s'\n",file);
137a168,171
> 	    }
> 	    i2d_X509_fp(fp, cert->x509_cert[i]);
> 	    g_free(file);
> 	    fclose(fp);
139,141d172
< 	i2d_X509_fp(fp, cert->x509_cert);
< 	g_free(file);
< 	fclose(fp);
146a178,187
>     int i;
>     char *ret = g_strdup("");
>     for (i=0; i<cert->certs; i++) {
> 	ret = g_strconcat(ret,ssl_X509_to_string(cert->x509_cert[i]),"\n",NULL);
>     }
>     return ret;
> }
> 
> char* ssl_X509_to_string(X509 *cert)
> {
155c196
< 	if (X509_NAME_get_text_by_NID(X509_get_issuer_name(cert->x509_cert), 
---
> 	if (X509_NAME_get_text_by_NID(X509_get_issuer_name(cert), 
160c201
< 	if (X509_NAME_get_text_by_NID(X509_get_issuer_name(cert->x509_cert), 
---
> 	if (X509_NAME_get_text_by_NID(X509_get_issuer_name(cert), 
163c204
< 		if (X509_NAME_get_text_by_NID(X509_get_issuer_name(cert->x509_cert), 
---
> 		if (X509_NAME_get_text_by_NID(X509_get_issuer_name(cert), 
166c207
< 	} else if (X509_NAME_get_text_by_NID(X509_get_issuer_name(cert->x509_cert), 
---
> 	} else if (X509_NAME_get_text_by_NID(X509_get_issuer_name(cert), 
172c213
< 	if (X509_NAME_get_text_by_NID(X509_get_issuer_name(cert->x509_cert), 
---
> 	if (X509_NAME_get_text_by_NID(X509_get_issuer_name(cert), 
179c220
< 	if (X509_NAME_get_text_by_NID(X509_get_subject_name(cert->x509_cert), 
---
> 	if (X509_NAME_get_text_by_NID(X509_get_subject_name(cert), 
184c225
< 	if (X509_NAME_get_text_by_NID(X509_get_subject_name(cert->x509_cert), 
---
> 	if (X509_NAME_get_text_by_NID(X509_get_subject_name(cert), 
187c228
< 		if (X509_NAME_get_text_by_NID(X509_get_subject_name(cert->x509_cert), 
---
> 		if (X509_NAME_get_text_by_NID(X509_get_subject_name(cert), 
190c231
< 	} else if (X509_NAME_get_text_by_NID(X509_get_subject_name(cert->x509_cert), 
---
> 	} else if (X509_NAME_get_text_by_NID(X509_get_subject_name(cert), 
196c237
< 	if (X509_NAME_get_text_by_NID(X509_get_subject_name(cert->x509_cert), 
---
> 	if (X509_NAME_get_text_by_NID(X509_get_subject_name(cert), 
203c244
< 	X509_digest(cert->x509_cert, EVP_md5(), md, &n);
---
> 	X509_digest(cert, EVP_md5(), md, &n);
207c248
< 	sig_status = ssl_certificate_check_signer(cert->x509_cert);
---
> 	sig_status = ssl_certificate_check_signer(cert);
209c250,253
< 	ret = g_strdup_printf(_("  Owner: %s (%s) in %s\n  Signed by: %s (%s) in %s\n  Fingerprint: %s\n  Signature status: %s"),
---
> 	ret = g_strdup_printf(_("  Owner: %s (%s) in %s\n"
> 				"  Signed by: %s (%s) in %s\n"
> 				"  Fingerprint: %s\n"
> 				"  Signature status: %s"),
235a280,281
>         int i;
> 
239,240c285,290
< 	if (cert->x509_cert)
< 		X509_free(cert->x509_cert);
---
> 	if (cert->x509_cert) {
> 	    for (i=0; i<cert->certs; i++) {
> 		X509_free(cert->x509_cert[i]);
> 	    }
> 	    free(cert->x509_cert);
> 	}
244d293
< 	cert = NULL;
249a299
> 	char *certno;
250a301,302
> 	int i;
> 
252,255c304,311
< 	file = g_strconcat(config_dir, G_DIR_SEPARATOR_S, 
< 			  "certs", G_DIR_SEPARATOR_S,
< 			  cert->host, ".", buf, ".cert", NULL);
< 	unlink (file);
---
> 	for (i=0; i<cert->certs; i++) {
> 	    certno = g_strdup_printf("%d", i);
> 	    file = g_strconcat(config_dir, G_DIR_SEPARATOR_S, 
> 			       "certs", G_DIR_SEPARATOR_S,
> 			       cert->host, ".", buf, ".", certno, ".cert", NULL);
> 	    unlink (file);
> 	    g_free(certno);
> 	}
259a316,319
> int scandir_select(const struct dirent *dirent) {
>     return !(strncmp(dirent->d_name,scandir_prefix,strlen(scandir_prefix)));
> }
> 
268a329
> 	char *certno = NULL;
271a333
> 	X509 **lst_x509;
272a335,339
> 	char *cert_dir;
> 	int i;
> 	int n;
> 	struct dirent **namelist;
> 	char *prefix;
279,282d345
< 	buf = g_strdup_printf("%d", port);
< 	file = g_strconcat(config_dir, G_DIR_SEPARATOR_S, 
< 			  "certs", G_DIR_SEPARATOR_S,
< 			  fqdn_host, ".", buf, ".cert", NULL);
283a347,354
> 	cert_dir = g_strconcat(config_dir, G_DIR_SEPARATOR_S, 
> 			       "certs", G_DIR_SEPARATOR_S, NULL);
> 	buf = g_strdup_printf("%d", port);
> 	prefix = g_strconcat(fqdn_host, ".", buf, NULL);
> 	scandir_prefix = prefix;
> 	n = scandir(cert_dir,&namelist,&scandir_select,alphasort);
> 	g_free(prefix);
> 	g_free(cert_dir);
285,286c356,383
< 	fp = fopen(file, "rb");
< 	if (fp == NULL) {
---
> 
> 	if (n < 0)
> 	    perror("scandir");
> 	else {
> 	    /* Not actually using the names - just wanted a count */
> 	    for (i=0; i<n; i++) {
> 		free(namelist[i]);
> 	    }
> 	    free(namelist);
> 	}
> 
> 	if (n<1) {
> 	    g_free(fqdn_host);
> 	    return NULL;
> 	}
> 	lst_x509 = malloc(sizeof(tmp_x509)*n);
> 	for (i=0; i<n; i++) {
> 	    certno = g_strdup_printf("%d", i+1);
> 	    buf = g_strdup_printf("%d", port);
> 	    file = g_strconcat(config_dir, G_DIR_SEPARATOR_S, 
> 			       "certs", G_DIR_SEPARATOR_S,
> 			       fqdn_host, ".", buf, ".", certno, ".cert", NULL);
> 	    g_free(certno);
> 	    g_free(buf);
> 	    fp = fopen(file, "rb");
> 	    if (fp == NULL) {
> 		fprintf(stderr,"Error: unable to open certificate file '%s'\n",
> 			file);
289c386,393
< 		return NULL;
---
> 		eb_debug(DBG_CORE,"Can't open certificate\n");
> 	    }
> 	    	    
> 	    if ((tmp_x509 = d2i_X509_fp(fp, 0)) != NULL) {
> 		lst_x509[i] = tmp_x509;
> 	    }
> 	    fclose(fp);
> 	    g_free(file);
291,298c395
< 	
< 	
< 	if ((tmp_x509 = d2i_X509_fp(fp, 0)) != NULL) {
< 		cert = ssl_certificate_new_lookup(tmp_x509, fqdn_host, port, lookup);
< 		X509_free(tmp_x509);
< 	}
< 	fclose(fp);
< 	g_free(file);
---
> 	cert = ssl_certificate_new_lookup(lst_x509, n, fqdn_host, port, lookup);
299a397,398
> 	for (i=0; i<n; i++)
> 	    X509_free(lst_x509[i]);
304c403
< static int ssl_certificate_compare (SSLCertificate *cert_a, SSLCertificate *cert_b)
---
> static int ssl_certificate_compare (X509 *x509_a, SSLCertificate *cert_b)
306,310c405,407
< 	if (cert_a == NULL || cert_b == NULL)
< 		return FALSE;
< 	else if (!X509_cmp(cert_a->x509_cert, cert_b->x509_cert))
< 		return TRUE;	
< 	else
---
>         int i;
> 
> 	if (x509_a == NULL || cert_b == NULL)
311a409,415
> 	else {
> 	    for (i=0; i<cert_b->certs; i++) {
> 		if (!X509_cmp(x509_a, cert_b->x509_cert[i]))
> 		    return TRUE;	
> 	    }
> 	}
> 	return FALSE;
369a474,491
> 				    cur_cert_str = ssl_certificate_to_string(current_cert);
> 				    err_msg = g_strdup_printf(
> 					_("New SSL certificate for %s:\n"
> 					  "%s\n\n"
> 					  "No certificates on file for this host,\n"
> 					  "but the signature is OK.\n"
> 					  "Do you want to continue connecting ?"),
> 					current_cert->host,
> 					cur_cert_str);
> 				    g_free (cur_cert_str);
> 
> 				    eb_do_no_callback_dialog( 
> 					err_msg, 
> 					"SSL certificate warning", 
> 					&result);
> 				
> 				    g_free(err_msg);
> 				    if (result) {
371,372c493,495
< 					ssl_certificate_destroy(current_cert);
< 					return TRUE;		
---
> 				    }
> 				    ssl_certificate_destroy(current_cert);
> 				    return result;		
397c520
< 	else if (!ssl_certificate_compare (current_cert, known_cert)) {
---
> 	else if (!ssl_certificate_compare (current_cert->x509_cert[0], known_cert)) {
403,404c526,530
< 		err_msg = g_strdup_printf(_("%s's SSL certificate changed!\nWe have saved this one:\n%s\n\nIt is now:\n%s\n\n"
< 					    "This could mean the server answering is not the known one.\n"
---
> 		err_msg = g_strdup_printf(_("%s's SSL certificate changed!\n"
> 					    "We have saved this:\n"
> 					    "%s\n\n"
> 					    "It is now:\n%s\n\n"
> 					    "This could mean the server answering is not a known one.\n"
417c543,544
< 			ssl_certificate_save(current_cert);	
---
> 		    ssl_certificate_append(current_cert->x509_cert[0],known_cert);
> 		    ssl_certificate_save(known_cert);	
419a547
> 		ssl_certificate_destroy(known_cert);
Index: ssl_certificate.h
===================================================================
RCS file: /home/cvsroot/ayttm/src/ssl_certificate.h,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 ssl_certificate.h
36,38c36,39
< 	X509 *x509_cert;
< 	char *host;
< 	int port;
---
>     int certs;
>     X509 **x509_cert;
>     char *host;
>     int port;
44a46
> char* ssl_X509_to_string(X509 *cert);
ayttmdiff3.txt (text/plain, 2.1 KB)
Index: status.c
===================================================================
RCS file: /home/cvsroot/ayttm/src/status.c,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 status.c
379c379,380
< 		
---
> 
> 		/*
384a386
> 		*/
918a921,943
> 
> /* Count number of online contacts */
> int count_online_contacts (void)
> {
>     LList * grps;
>     LList * contacts;
> 
>     int qonline = 0;
>     
>     grouplist * grp;
>     struct contact * con;
>     
>     for (grps = groups; grps; grps = grps->next) {
> 	grp = grps->data;
> 	for (contacts = grp->members; contacts; contacts = contacts->next) {
> 	    con = contacts->data;
> 	    if (con->online) 
> 		qonline++;
> 	}
>     }
>     return qonline;
> }
> 	    
1110a1136,1138
> 	time_t t;
> 	struct tm * cur_time;
> 
1123,1125c1151,1158
< 			g_snprintf(buff, 1024, _("%s is now %s"), 
< 					ea->account_contact->nick,
< 					strlen(tmp)?tmp:"Online");
---
> 			time(&t);
> 			cur_time = localtime(&t);
> 			g_snprintf(buff, 1024, _("%s is %s %02d:%02d:%02d"), 
> 				   ea->account_contact->nick,
> 				   strlen(tmp)?tmp:"Online",
> 				   cur_time->tm_hour,
> 				   cur_time->tm_min,
> 				   cur_time->tm_sec);
1572a1606,1607
> 	int qonline;
> 
1579c1614
< 		window_title_handler = eb_timeout_add(5000, 
---
> 		window_title_handler = eb_timeout_add(10000, 
1582a1618,1624
> 	    /* show # of buddies online */
> 	    qonline=count_online_contacts();
> 	    if (qonline>0)
> 		title = g_strdup_printf("%d online contact%s", 
> 					qonline,
> 					qonline>1?"s":"");
> 	    else
1597a1640,1642
> 	time_t t;
> 	struct tm * cur_time;
> 
1622c1667,1672
< 	g_snprintf(buff, 1024, _("%s is now Online"), ec->nick);
---
> 	time(&t);
> 	cur_time = localtime(&t);
> 	g_snprintf(buff, 1024, _("%s is Online %02d:%02d:%02d"), ec->nick,
> 		   cur_time->tm_hour,
> 		   cur_time->tm_min,
> 		   cur_time->tm_sec);
1630a1681,1683
> 	time_t t;
> 	struct tm * cur_time;
> 
1656c1709,1714
< 	g_snprintf(buff, 1024, _("%s is now Offline"), ec->nick);
---
> 	time(&t);
> 	cur_time = localtime(&t);
> 	g_snprintf(buff, 1024, _("%s is Offline %02d:%02d:%02d"), ec->nick,
> 		   cur_time->tm_hour,
> 		   cur_time->tm_min,
> 		   cur_time->tm_sec);
ayttmdiff4.txt (text/plain, 507 B)
Index: image_window.c
===================================================================
RCS file: /home/cvsroot/ayttm/src/image_window.c,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 image_window.c
30a31,33
> unsigned char *(*image_2_jpg)(const unsigned char *, long *) = NULL;
> unsigned char *(*image_2_jpc)(const unsigned char *, long *) = NULL;
> 
67,69d69
< 
< unsigned char *(*image_2_jpg)(const unsigned char *, long *) = NULL;
< unsigned char *(*image_2_jpc)(const unsigned char *, long *) = NULL;
smime.p7s (application/x-pkcs7-signature, 3.6 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.