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

Annotation of /trunk/Src/wptDNSKeys.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 248 - (hide annotations)
Fri Jul 28 11:11:09 2006 UTC (18 years, 7 months ago) by twoaday
Original Path: trunk/PTD/wptDNSKeys.cpp
File size: 4095 byte(s)
Prepare 1.0.0pre2 release.


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    
25     /* typedef for the function signature. */
26     typedef DNS_STATUS (*dns_query_fnc) (LPSTR, WORD, DWORD, PIP4_ARRAY,
27     PDNS_RECORD*, PVOID *);
28     /* function pointer. */
29     static dns_query_fnc dns_query = NULL;
30    
31     /* hinstance handle to the DLL. */
32     static HINSTANCE dns_api = NULL;
33    
34     /* 1 if the DNS api is not available. */
35     static int dns_failed = 0;
36    
37    
38     /*
39     DNS_STATUS WINAPI DnsQuery (
40     LPSTR lpstrName, WORD wType,
41     DWORD fOptions, PIP4_ARRAY aipServers,
42     PDNS_RECORD *ppQueryResultsSet,
43     PVOID *pReserved
44     );
45     */
46    
47     struct pka_info_s {
48     int ver;
49     char *fpr;
50     char *uri;
51     };
52     typedef struct pka_info_s *pka_info_t;
53    
54    
55     /* Initialize the DNS sub system. We do this via dynamic loading
56     because older NT/9X systems do not have this API. */
57     static int
58     dns_init (void)
59     {
60     if (dns_query)
61     return 0;
62     if (dns_failed)
63     return -1;
64     dns_api = LoadLibrary ("dnsapi");
65     if (!dns_api) {
66     dns_failed = 1;
67     return -1;
68     }
69     dns_query = (dns_query_fnc)GetProcAddress (dns_api, "DnsQuery_A");
70     if (!dns_query) {
71     dns_failed = 1;
72     return -1;
73     }
74     return 0;
75     }
76    
77     /* Cleanup static structs. */
78     void
79     dns_cleanup (void)
80     {
81     if (dns_api)
82     FreeLibrary (dns_api);
83     dns_api = NULL;
84     }
85    
86    
87     /* Release the memory of the @pka structure. */
88     void
89     dns_free_pka_record (pka_info_t pka)
90     {
91     if (pka->fpr)
92     free (pka->fpr);
93     if (pka->uri)
94     free (pka->uri);
95     free (pka);
96     }
97    
98    
99    
100     /* build a DNS name for the PKA lookup. */
101     static char*
102     email_get_pka_addr (const char *uid)
103     {
104     const char *fmt = "._pka.";
105     char *bo;
106     char *pka;
107     int pos=0;
108    
109     if ((bo=strchr (uid, '<')) && strchr (uid, '>'))
110     uid += (bo-uid+1);
111     if (!strchr (uid, '@'))
112     return NULL;
113    
114     pka = (char*)calloc (1, strlen (uid)+strlen (fmt)+1);
115     while (uid && *uid != '@')
116     pka[pos++] = *uid++;
117     uid++;
118     strcat (pka, "._pka."); pos += strlen (fmt);
119     while (uid && *uid && *uid != '>')
120     pka[pos++] = *uid++;
121     return pka;
122     }
123    
124    
125     /* Convert the returned data from the PKA (txt) record. */
126     pka_info_t
127     parse_pka_data (const char *data)
128     {
129     enum pka_col_t { COL_VER=1, COL_FPR, COL_URI };
130     pka_info_t pka;
131     char *p;
132     int pos = 1;
133    
134     if (strncmp (data, "v=pka1;", 8))
135     return NULL;
136     pka = (pka_info_t)calloc (1, sizeof *pka);
137     p = strtok ((char*)data, ";");
138     while (p != NULL) {
139     switch (pos) {
140     case COL_VER:
141     pka->ver = 1;
142     break;
143    
144     case COL_FPR:
145     pka->fpr = strdup (p+strlen ("fpr="));
146     break;
147    
148     case COL_URI: /* optional */
149     pka->uri = strdup (p+strlen ("uri="));
150     break;
151    
152     default:
153     break;
154     }
155     pos++;
156     }
157     if (pos != 3) {
158     dns_free_pka_record (pka);
159     pka = NULL;
160     }
161    
162     return pka;
163     }
164    
165    
166     /* Retrieve a PKA record from the DNS.
167     @userid is used to extract the email address. */
168     int
169     dns_get_pka_record (const char *userid, pka_info_t *r_pka)
170     {
171     char *addr;
172     DNS_STATUS err;
173     DNS_RECORD *rec;
174    
175     *r_pka = NULL;
176     if (dns_init ())
177     return -1;
178     addr = email_get_pka_addr (userid);
179     if (!addr)
180     return -1;
181     err = dns_query (addr, DNS_TYPE_TEXT, 0, NULL, &rec, NULL);
182     if (err) {
183     free (addr);
184     return -1;
185     }
186     *r_pka = parse_pka_data (rec->Data.Txt.pStringArray[0]);
187    
188     //DnsRecordListFree (rec, DnsFreeRecordList);
189     free (addr);
190     return 0;
191     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26