source: roaraudio/libroar/auth.c @ 3228:ba545e1a7a77

Last change on this file since 3228:ba545e1a7a77 was 3228:ba545e1a7a77, checked in by phi, 14 years ago

try multible auth metodes if server does not accept us

File size: 7.2 KB
Line 
1//auth.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2010
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 *  NOTE for everyone want's to change something and send patches:
24 *  read README and HACKING! There a addition information on
25 *  the license of this document you need to read before you send
26 *  any patches.
27 *
28 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
29 *  or libpulse*:
30 *  The libs libroaresd, libroararts and libroarpulse link this lib
31 *  and are therefore GPL. Because of this it may be illigal to use
32 *  them with any software that uses libesd, libartsc or libpulse*.
33 */
34
35#include "libroar.h"
36
37/* How auth works:
38 * 0) set stage to zero
39 * 1) get server address and local node name (from uname())
40 * 2) look up authfile/authdb/authservice for the server+local address + stage.
41 *    if no data was found send NONE-Auth.
42 * 3) send data to server
43 * 4) read answer from server
44 * 5) if stage of server response is non-zero increment stage to server stage+1
45 *    and repeat from step 2)
46 * 6) check if we got an OK or an ERROR, return currect value
47 */
48
49/* The protocol:
50 * Auth request:
51 * Byte 0: auth type
52 * Byte 1: stage
53 * Byte 2: reserved (must be zero)
54 * Byte 3: reserved (must be zero)
55 * Byte 4-end: auth type depending data.
56 *
57 * If no data is to be send bytes 2 and 3 can be omitted.
58 * If no data is to be send and stage is zero bytes 1, 2 and 3 can be omitted.
59 *
60 * Auth response:
61 * The same as the auth request.
62 * if the server sends an zero size message back it means the server accepted our connection
63 * and no additional stage is needed.
64 * if the message type is OK the server accepted our auth.
65 * if the message type is ERROR the server recjected us. we may try other auth methodes.
66 * if the server accepted our data and the stage is non-zero we need to continue with the next
67 * stage of the auth.
68 * if the server rejected us the auth type value of the response is a suggested next auth type
69 * we should try if possible. This may help the client to find a working auth type.
70 */
71
72/* The protocol by auth type:
73 *
74 * --- NONE:
75 * No data is send, the server accepts the connect or rejects it depending on some
76 * magic within the server. we do not care about this.
77 * The data block is not used.
78 *
79 * --- COOKIE:
80 * We send cookies for all stages the server ask us to provide a cookie.
81 * if a cookie is wrong the server rejects us or aks us for another.
82 * The cookie is send as binary data in the data block.
83 *
84 * --- TRUST:
85 * We ask the server to auth us based on ower UID/GID/PID.
86 * The server may reject this becasue we are not allowed or because it is not
87 * supported by the transport.
88 * If we get rejected we may try to continue with IDENT then RHOST before we use NONE.
89 * The data block is not used.
90 *
91 * --- PASSWORD:
92 * This is technikly the same as COOKIE just that the cookie is limited to
93 * printable ASCII chars and that the user should be asked to provide the password.
94 * This may be done via a GUI popup window.
95 *
96 * --- SYSUSER:
97 * We provide a Username + Password for a system user.
98 * The data block contains of two main parts:
99 * The first part is a one byte long subtype.
100 * The value must be 0x01 for username+password.
101 * futur versions may define other types.
102 * the secund part is the actual data block.
103 * for username+password it is splited into two fields, both terminated with \0.
104 * the first is the username the last one the password as clear text.
105 * Example: char data[] = "\001MyUser\0MyPassword\0";
106 *
107 * --- OPENPGP_SIGN:
108 *
109 * --- OPENPGP_ENCRYPT:
110 *
111 * --- OPENPGP_AUTH:
112 *
113 * --- KERBEROS:
114 * We use Kerberos to auth.
115 *
116 * --- RHOST:
117 * The server is asked to auth us based on our source address.
118 * The data block is not used.
119 *
120 * --- XAUTH:
121 * We send an X11 Cookie.
122 *
123 * --- IDENT:
124 * The server is asked to auth us based on our source address using the IDENT protocol.
125 * The data block is not used.
126 *
127 */
128
129static int roar_auth_ask_server (struct roar_connection * con, struct roar_auth_message * authmes) {
130 struct roar_message   mes;
131 char                * header = mes.data;
132 int                   ret;
133
134 memset(&mes, 0, sizeof(struct roar_message)); // make valgrind happy!
135
136 mes.cmd     = ROAR_CMD_AUTH;
137 mes.datalen = 4;
138
139 header[0] = authmes->type;
140 header[1] = authmes->stage;
141 header[2] = authmes->reserved.c[0];
142 header[3] = authmes->reserved.c[1];
143
144 if ( (ret = roar_req(con, &mes, NULL)) == -1 )
145  return -1;
146
147 if ( mes.datalen < 4 ) {
148  memset(header+mes.datalen, 0, 4-mes.datalen);
149 }
150
151 authmes->type          = header[0];
152 authmes->stage         = header[1];
153 authmes->reserved.c[0] = header[2];
154 authmes->reserved.c[1] = header[3];
155
156 return 0;
157}
158
159static void roar_auth_mes_init(struct roar_auth_message * authmes, int type) {
160 memset(authmes, 0, sizeof(struct roar_auth_message));
161
162 authmes->type  = type;
163 authmes->stage = 0;
164 authmes->data  = NULL;
165 authmes->len   = 0;
166}
167
168#define _EOL ROAR_AUTH_T_AUTO
169int roar_auth   (struct roar_connection * con) {
170 struct roar_auth_message authmes;
171 int ret;
172 int i;
173 int ltt[] = {
174              ROAR_AUTH_T_TRUST,
175              ROAR_AUTH_T_IDENT,
176              ROAR_AUTH_T_RHOST,
177              ROAR_AUTH_T_NONE,
178              _EOL
179             };
180
181 for (i = 0; ltt[i] != _EOL; i++) {
182  roar_auth_mes_init(&authmes, ltt[i]);
183
184  if ( (ret = roar_auth_ask_server(con, &authmes)) == -1 )
185   continue;
186
187  if ( authmes.stage != 0 )
188   continue;
189
190  return 0;
191 }
192
193 return -1;
194}
195
196// String functions:
197static struct {
198 int    type;
199 char * name;
200} _g_authts[] = {
201// grep ^'#define ROAR_AUTH_T_' auth.h | while read d t d; do n=$(cut -d_ -f4 <<<$t | tr A-Z a-z); printf ' {%-28s %-10s},\n' $t, \"$n\"; done
202 {ROAR_AUTH_T_NONE,            "none"    },
203 {ROAR_AUTH_T_COOKIE,          "cookie"  },
204 {ROAR_AUTH_T_TRUST,           "trust"   },
205 {ROAR_AUTH_T_PASSWORD,        "password"},
206 {ROAR_AUTH_T_SYSUSER,         "sysuser" },
207 {ROAR_AUTH_T_OPENPGP_SIGN,    "openpgp" },
208 {ROAR_AUTH_T_OPENPGP_ENCRYPT, "openpgp" },
209 {ROAR_AUTH_T_OPENPGP_AUTH,    "openpgp" },
210 {ROAR_AUTH_T_KERBEROS,        "kerberos"},
211 {ROAR_AUTH_T_RHOST,           "rhost"   },
212 {ROAR_AUTH_T_XAUTH,           "xauth"   },
213 {ROAR_AUTH_T_IDENT,           "ident"   },
214 {-1, NULL}
215};
216
217int    roar_str2autht(char * str) {
218 int i;
219
220 for (i = 0; _g_authts[i].name != NULL; i++)
221  if ( !strcasecmp(_g_authts[i].name, str) )
222   return _g_authts[i].type;
223
224 return -1;
225}
226
227char * roar_autht2str(int auth) {
228 int i;
229
230 for (i = 0; _g_authts[i].name != NULL; i++)
231  if ( _g_authts[i].type == auth )
232   return _g_authts[i].name;
233
234 return "(UNKNOWN)";
235}
236
237//ll
Note: See TracBrowser for help on using the repository browser.