/[winpt]/trunk/PTD/wptDNSKeys.cpp
ViewVC logotype

Contents of /trunk/PTD/wptDNSKeys.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 273 - (show annotations)
Fri Dec 8 10:22:17 2006 UTC (18 years, 2 months ago) by twoaday
File size: 4330 byte(s)


1 /* wptDNSKeys.cpp - Support for retrieving keys via DNS
2 * Copyright (C) 2006 Timo Schulz
3 *
4 * This file is part of WinPT.
5 *
6 * WinPT is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * WinPT is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with WinPT; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #include <windows.h>
22 #include <windns.h>
23
24 #include "wptDNSKeys.h"
25
26
27 /* typedef for the function signature. */
28 typedef DNS_STATUS (*dns_query_fnc) (LPSTR, WORD, DWORD, PIP4_ARRAY,
29 PDNS_RECORD*, PVOID *);
30
31 typedef void (*dns_record_list_free_fnc) (PDNS_RECORD, DNS_FREE_TYPE);
32
33 /* function pointer. */
34 static dns_query_fnc dns_query = NULL;
35 static dns_record_list_free_fnc dns_record_free = NULL;
36
37 /* hinstance handle to the DLL. */
38 static HINSTANCE dns_api = NULL;
39
40 /* 1 if the DNS api is not available. */
41 static int dns_failed = 0;
42
43
44
45 /* Initialize the DNS sub system. We do this via dynamic loading
46 because older NT/9X systems do not have this API. */
47 static int
48 dns_init (void)
49 {
50 if (dns_query)
51 return 0;
52 if (dns_failed)
53 return -1;
54 dns_api = LoadLibrary ("dnsapi");
55 if (!dns_api) {
56 dns_failed = 1;
57 return -1;
58 }
59 dns_query = (dns_query_fnc)GetProcAddress (dns_api, "DnsQuery_A");
60 if (!dns_query) {
61 dns_failed = 1;
62 return -1;
63 }
64 dns_record_free = (dns_record_list_free_fnc)GetProcAddress (dns_api, "DnsRecordListFree");
65 if (!dns_record_free) {
66 dns_failed = 1;
67 return -1;
68 }
69 return 0;
70 }
71
72
73 /* Cleanup static structs. */
74 void
75 dns_cleanup (void)
76 {
77 if (dns_api)
78 FreeLibrary (dns_api);
79 dns_api = NULL;
80 dns_failed = 0;
81 }
82
83
84 /* build a DNS name for the PKA lookup. */
85 static char*
86 email_get_pka_addr (const char *uid)
87 {
88 const char *fmt = "._pka.";
89 char *bo;
90 char *pka;
91 int pos=0;
92
93 /* check that the @uid really contains an email address. */
94 if ((bo=strchr (uid, '<')) && strchr (uid, '>'))
95 uid += (bo-uid+1);
96 if (!strchr (uid, '@'))
97 return NULL;
98
99 /* create the user@_pka.domain-part.tlp string. */
100 pka = (char*)calloc (1, strlen (uid)+strlen (fmt)+1);
101 while (uid && *uid != '@')
102 pka[pos++] = *uid++;
103 uid++;
104 strcat (pka, fmt); pos += strlen (fmt);
105 while (uid && *uid && *uid != '>')
106 pka[pos++] = *uid++;
107 return pka;
108 }
109
110
111 /* Convert the returned data from the PKA (txt) record. */
112 pka_info_t
113 parse_pka_data (const char *data)
114 {
115 enum pka_col_t { COL_VER=1, COL_FPR, COL_URI };
116 pka_info_t pka;
117 char *p;
118 int pos = 1;
119
120 if (strncmp (data, "v=pka1;", 8))
121 return NULL;
122 pka = (pka_info_t)calloc (1, sizeof *pka);
123 p = strtok ((char*)data, ";");
124 while (p != NULL) {
125 switch (pos) {
126 case COL_VER:
127 pka->ver = 1;
128 break;
129
130 case COL_FPR:
131 pka->fpr = strdup (p+strlen ("fpr="));
132 break;
133
134 case COL_URI: /* optional */
135 pka->uri = strdup (p+strlen ("uri="));
136 break;
137
138 default:
139 break;
140 }
141 pos++;
142 }
143 if (pos != 3) {
144 dns_free_pka_record (pka);
145 pka = NULL;
146 }
147
148 return pka;
149 }
150
151
152 /* Retrieve a PKA record from the DNS.
153 @userid is used to extract the email address. */
154 extern "C" int
155 dns_get_pka_record (const char *userid, pka_info_t *r_pka)
156 {
157 char *addr;
158 DNS_STATUS err;
159 DNS_RECORD *rec;
160
161 *r_pka = NULL;
162 if (dns_init ())
163 return -1;
164 addr = email_get_pka_addr (userid);
165 if (!addr)
166 return -1;
167 err = dns_query (addr, DNS_TYPE_TEXT, 0, NULL, &rec, NULL);
168 if (err) {
169 free (addr);
170 return -1;
171 }
172 *r_pka = parse_pka_data (rec->Data.Txt.pStringArray[0]);
173
174 dns_record_free (rec, DnsFreeRecordList);
175 free (addr);
176 return 0;
177 }
178
179
180 /* Release the memory of the @pka structure. */
181 extern "C" void
182 dns_free_pka_record (pka_info_t pka)
183 {
184 if (pka->fpr)
185 free (pka->fpr);
186 pka->fpr = NULL;
187 if (pka->uri)
188 free (pka->uri);
189 pka->uri = NULL;
190 free (pka);
191 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26