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

Annotation of /trunk/PTD/wptDNSKeys.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 273 - (hide annotations)
Fri Dec 8 10:22:17 2006 UTC (18 years, 2 months ago) by twoaday
File size: 4330 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 256 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 twoaday 248 return 0;
70     }
71    
72 twoaday 256
73 twoaday 248 /* Cleanup static structs. */
74     void
75     dns_cleanup (void)
76     {
77     if (dns_api)
78     FreeLibrary (dns_api);
79     dns_api = NULL;
80 twoaday 256 dns_failed = 0;
81 twoaday 248 }
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 twoaday 273 /* check that the @uid really contains an email address. */
94 twoaday 248 if ((bo=strchr (uid, '<')) && strchr (uid, '>'))
95     uid += (bo-uid+1);
96     if (!strchr (uid, '@'))
97     return NULL;
98    
99 twoaday 273 /* create the user@_pka.domain-part.tlp string. */
100 twoaday 248 pka = (char*)calloc (1, strlen (uid)+strlen (fmt)+1);
101     while (uid && *uid != '@')
102     pka[pos++] = *uid++;
103     uid++;
104 twoaday 261 strcat (pka, fmt); pos += strlen (fmt);
105 twoaday 248 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 twoaday 256 extern "C" int
155 twoaday 248 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 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     if (pka->fpr)
185     free (pka->fpr);
186 twoaday 261 pka->fpr = NULL;
187 twoaday 256 if (pka->uri)
188     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