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

Contents of /trunk/PTD/wptDNSKeys.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 305 - (show annotations)
Fri Mar 23 11:32:28 2007 UTC (17 years, 11 months ago) by twoaday
File size: 4354 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)
65 GetProcAddress (dns_api, "DnsRecordListFree");
66 if (!dns_record_free) {
67 dns_failed = 1;
68 return -1;
69 }
70 return 0;
71 }
72
73
74 /* Cleanup static structs. */
75 void
76 dns_cleanup (void)
77 {
78 if (dns_api != NULL)
79 FreeLibrary (dns_api);
80 dns_api = NULL;
81 dns_failed = 0;
82 }
83
84
85 /* build a DNS name for the PKA lookup. */
86 static char*
87 email_get_pka_addr (const char *uid)
88 {
89 const char *fmt = "._pka.";
90 char *bo;
91 char *pka;
92 int pos=0;
93
94 /* check that the @uid really contains an email address. */
95 if ((bo=strchr (uid, '<')) && strchr (uid, '>'))
96 uid += (bo-uid+1);
97 if (!strchr (uid, '@'))
98 return NULL;
99
100 /* create the user@_pka.domain-part.tlp string. */
101 pka = (char*)calloc (1, strlen (uid)+strlen (fmt)+1);
102 while (uid && *uid != '@')
103 pka[pos++] = *uid++;
104 uid++;
105 strcat (pka, fmt); pos += strlen (fmt);
106 while (uid && *uid && *uid != '>')
107 pka[pos++] = *uid++;
108 return pka;
109 }
110
111
112 /* Convert the returned data from the PKA (txt) record. */
113 pka_info_t
114 parse_pka_data (const char *data)
115 {
116 enum pka_col_t { COL_VER=1, COL_FPR, COL_URI };
117 pka_info_t pka;
118 char *p;
119 int pos = 1;
120
121 if (strncmp (data, "v=pka1;", 8))
122 return NULL;
123 pka = (pka_info_t)calloc (1, sizeof *pka);
124 p = strtok ((char*)data, ";");
125 while (p != NULL) {
126 switch (pos) {
127 case COL_VER:
128 pka->ver = 1;
129 break;
130
131 case COL_FPR:
132 pka->fpr = strdup (p+strlen ("fpr="));
133 break;
134
135 case COL_URI: /* optional */
136 pka->uri = strdup (p+strlen ("uri="));
137 break;
138
139 default:
140 break;
141 }
142 pos++;
143 }
144 if (pos != 3) {
145 dns_free_pka_record (pka);
146 pka = NULL;
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 DNS_STATUS err;
158 DNS_RECORD *rec;
159 char *addr;
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 != NULL)
185 free (pka->fpr);
186 pka->fpr = NULL;
187 if (pka->uri != NULL)
188 free (pka->uri);
189 pka->uri = NULL;
190 free (pka);
191 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26