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

Annotation of /trunk/PTD/wptDNSKeys.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 305 - (hide annotations)
Fri Mar 23 11:32:28 2007 UTC (17 years, 11 months ago) by twoaday
File size: 4354 byte(s)


1 twoaday 248 /* 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 twoaday 256 #include "wptDNSKeys.h"
25 twoaday 248
26 twoaday 256
27 twoaday 248 /* typedef for the function signature. */
28     typedef DNS_STATUS (*dns_query_fnc) (LPSTR, WORD, DWORD, PIP4_ARRAY,
29     PDNS_RECORD*, PVOID *);
30 twoaday 256
31     typedef void (*dns_record_list_free_fnc) (PDNS_RECORD, DNS_FREE_TYPE);
32    
33 twoaday 248 /* function pointer. */
34     static dns_query_fnc dns_query = NULL;
35 twoaday 256 static dns_record_list_free_fnc dns_record_free = NULL;
36 twoaday 248
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 twoaday 305 dns_record_free = (dns_record_list_free_fnc)
65     GetProcAddress (dns_api, "DnsRecordListFree");
66 twoaday 256 if (!dns_record_free) {
67     dns_failed = 1;
68     return -1;
69     }
70 twoaday 248 return 0;
71     }
72    
73 twoaday 256
74 twoaday 248 /* Cleanup static structs. */
75     void
76     dns_cleanup (void)
77     {
78 twoaday 305 if (dns_api != NULL)
79 twoaday 248 FreeLibrary (dns_api);
80     dns_api = NULL;
81 twoaday 256 dns_failed = 0;
82 twoaday 248 }
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 twoaday 273 /* check that the @uid really contains an email address. */
95 twoaday 248 if ((bo=strchr (uid, '<')) && strchr (uid, '>'))
96     uid += (bo-uid+1);
97     if (!strchr (uid, '@'))
98     return NULL;
99    
100 twoaday 273 /* create the user@_pka.domain-part.tlp string. */
101 twoaday 248 pka = (char*)calloc (1, strlen (uid)+strlen (fmt)+1);
102     while (uid && *uid != '@')
103     pka[pos++] = *uid++;
104     uid++;
105 twoaday 261 strcat (pka, fmt); pos += strlen (fmt);
106 twoaday 248 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 twoaday 256 extern "C" int
155 twoaday 248 dns_get_pka_record (const char *userid, pka_info_t *r_pka)
156     {
157     DNS_STATUS err;
158     DNS_RECORD *rec;
159 twoaday 305 char *addr;
160 twoaday 248
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 twoaday 256 dns_record_free (rec, DnsFreeRecordList);
175 twoaday 248 free (addr);
176     return 0;
177     }
178 twoaday 256
179    
180     /* Release the memory of the @pka structure. */
181     extern "C" void
182     dns_free_pka_record (pka_info_t pka)
183     {
184 twoaday 305 if (pka->fpr != NULL)
185 twoaday 256 free (pka->fpr);
186 twoaday 261 pka->fpr = NULL;
187 twoaday 305 if (pka->uri != NULL)
188 twoaday 256 free (pka->uri);
189 twoaday 261 pka->uri = NULL;
190 twoaday 256 free (pka);
191     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26