1 /**********************************************************************
2  * greeting.c                                              October 1999
3  * Horms                                             horms@verge.net.au
4  *
5  * Protocol independent greeting
6  *
7  * perdition
8  * Mail retrieval proxy server
9  * Copyright (C) 1999-2005  Horms
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of the
14  * License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  **********************************************************************/
26 
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30 
31 #include "greeting.h"
32 #include "options.h"
33 #include "perdition_globals.h"
34 #include "sock.h"
35 
36 #ifdef DMALLOC
37 #include <dmalloc.h>
38 #endif
39 
40 
41 /**********************************************************************
42  * greeting_checksum
43  * Produce a checksum for greeting string
44  * pre: csum: checksum will be returned here
45  * post: Checksum of the output of log_options_str() is checksumed
46  *       using str_rolling32() and stored in csum.
47  * return: 0 on success
48  *         -1 on error
49  **********************************************************************/
50 
greeting_checksum(uint32 * csum)51 static int greeting_checksum(uint32 *csum)
52 {
53 	char **a, **p;
54 
55 	a = log_options_str();
56 	if (!a) {
57 		VANESSA_LOGGER_DEBUG("log_options_str");
58 		return -1;
59 	}
60 
61 	*csum = 0;
62 	for (p = a; *p; p++)
63 		*csum += str_rolling32((unsigned char *)*p, strlen(*p));
64 
65 	log_options_str_free(a);
66 
67 	return 0;
68 }
69 
getnameinfo_try_lookup(struct sockaddr * addr,char * host,size_t hostlen)70 int getnameinfo_try_lookup(struct sockaddr *addr, char *host, size_t hostlen)
71 {
72 	int rc = EAI_AGAIN;
73 
74 	if (!opt.no_lookup)
75 		rc = getnameinfo(addr, perdition_get_salen(addr),
76 				 host, hostlen, NULL, 0, 0);
77 
78 	if (rc == EAI_AGAIN)
79 		/* Try again for a numeric host */
80 		rc = getnameinfo(addr, perdition_get_salen(addr),
81 				 host, hostlen, NULL, 0, NI_NUMERICHOST);
82 
83 	if (rc)
84 		VANESSA_LOGGER_DEBUG_UNSAFE("getnameinfo sockname: %s",
85 					    gai_strerror(rc));
86 
87 	return rc;
88 }
89 
90 /**********************************************************************
91  * greeting_str
92  * Produce greeting string
93  * pre: base: Base string for greeting
94  *      flag: Flags as per greeting.h
95  * post: Protocol specific message string is formed
96  * return message string on success
97  *        NULL on error
98  **********************************************************************/
99 
greeting_str(const char * base,flag_t flag)100 char *greeting_str(const char *base, flag_t flag)
101 {
102   char *message;
103   char host[NI_MAXHOST];
104   uint32 csum;
105   char csum_str[10];
106   int rc;
107 
108   if(greeting_checksum(&csum) < 0) {
109 	  VANESSA_LOGGER_DEBUG("greeting_checksum");
110 	  return(NULL);
111   }
112   snprintf(csum_str, sizeof(csum_str) - 1, "%08x", csum);
113   csum_str[sizeof(csum_str)-1] = '\0';
114 
115   if(flag&GREETING_ADD_NODENAME){
116     if (!opt.no_bind_banner && sockname) {
117       rc = getnameinfo_try_lookup((struct sockaddr *)sockname,
118 				  host, NI_MAXHOST);
119       if (rc) {
120         VANESSA_LOGGER_DEBUG("getnameinfo_try_lookup");
121         return NULL;
122       }
123     }
124     else{
125       strncpy(host, system_uname->nodename, NI_MAXHOST -1);
126     }
127     if((message=str_cat(5, base, " ", host, " ", csum_str))==NULL){
128       VANESSA_LOGGER_DEBUG("str_cat");
129       return(NULL);
130     }
131   }
132   else{
133     if((message=strdup(base))==NULL){
134       VANESSA_LOGGER_DEBUG("strdup");
135       return(NULL);
136     }
137   }
138   return(message);
139 }
140