1/*
2**    BPALogin - lightweight portable BIDS2 login client
3**    Copyright (c) 2001-3 Shane Hyde, and others.
4** 
5**  This program is free software; you can redistribute it and/or modify
6**  it under the terms of the GNU General Public License as published by
7**  the Free Software Foundation; either version 2 of the License, or
8**  (at your option) any later version.
9** 
10**  This program is distributed in the hope that it will be useful,
11**  but WITHOUT ANY WARRANTY; without even the implied warranty of
12**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13**  GNU General Public License for more details.
14** 
15**  You should have received a copy of the GNU General Public License
16**  along with this program; if not, write to the Free Software
17**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
19*/ 
20
21/**
22 * Changes:
23 * 
24 * 2001-12-05:  wdrose     Added errno.h to list of UNIX-only includes.
25 */
26
27#include <stdlib.h>
28#include <stdio.h>
29#include <stdarg.h>
30#include <string.h>
31
32#ifndef _WIN32
33#include <unistd.h>
34#include <errno.h>
35#include <sys/time.h>
36#include <sys/socket.h>
37#include <netinet/in.h>
38#include <netdb.h>
39#include <syslog.h>
40#include <arpa/inet.h>
41#endif
42
43#include <time.h>
44#include <signal.h>
45#include <sys/types.h>
46
47#ifdef _WIN32
48#include <winsock.h>
49#endif
50
51/*
52**  Win32 & BeOS use a closesocket call, and unices use a close call, this define fixes this up
53*/
54#ifndef _WIN32
55int closesocket(int);
56//#define closesocket close
57#endif
58
59
60#ifdef _WIN32
61#define NOSYSLOG
62#define HAS_VNSPRINTF
63
64#define sleep(x) Sleep((x)*1000)
65#endif
66
67/*
68** This is needed for compiling with EMX under OS/2
69*/
70#ifdef __EMX__
71  #define strcasecmp stricmp
72#endif
73
74
75#define TRUE 1
76#define FALSE 0
77
78#define LOGIN_SOFTWARE "bpalogin"
79#define LOGIN_VERSION  1
80
81#define MAXUSERNAME 25
82#define MAXPASSWORD 25
83#define MAXAUTHSERVER 80
84#define MAXAUTHDOMAIN 80
85#define MAXLOGINPROG 256
86#define MAXCONFFILE 256
87#define MAXLOCALADDRESS 32
88#define MAXDDNSCONFFILE 256
89
90#define DEFAULT_DEBUG         1
91#define DEFAULT_AUTHSERVER    "sm-server"
92#define DEFAULT_AUTHDOMAIN    ""
93#define DEFAULT_AUTHPORT      5050
94#define DEFAULT_CONFFILE      "@@BPALOGIN_CONF@@"
95/*
96** state engine codes
97*/
98#define STATE_NEED_PROTOCOL 0
99#define STATE_SEND_PROT_REQ 1
100#define STATE_AWAIT_NEG_RESP 2
101#define STATE_SEND_LOGIN_REQ 3
102#define STATE_AWAIT_LOGIN_AUTH_RESP 4
103#define STATE_SEND_LOGIN_AUTH_REQ 5
104#define STATE_AWAIT_LOGIN_RESP 6
105#define STATE_SEND_LOGOUT_REQ 7
106#define STATE_AWAIT_LOGOUT_AUTH_RESP 8
107#define STATE_SEND_LOGOUT_AUTH_REQ 9
108#define STATE_AWAIT_LOGOUT_RESP 10
109#define STATE_IDLE_LOGIN 11
110#define STATE_RECEIVED_STATUS_REQ 12
111#define STATE_RECEIVED_RESTART_REQ 13
112#define STATE_IDLE_LOGOFF 14
113
114/*
115** message type codes
116*/
117#define T_MSG_MIN 1
118#define T_MSG_PROTOCOL_NEG_REQ 1
119#define T_MSG_PROTOCOL_NEG_RESP 2
120#define T_MSG_LOGIN_REQ 3
121#define T_MSG_LOGIN_AUTH_REQ 4
122#define T_MSG_LOGIN_RESP 5
123#define T_MSG_LOGOUT_REQ 6
124#define T_MSG_LOGOUT_AUTH_RESP 7
125#define T_MSG_LOGOUT_RESP 8
126#define T_MSG_AUTH_RESP 9
127#define T_MSG_AUTH_REQ 10
128#define T_MSG_STATUS_REQ 11
129#define T_MSG_STATUS_RESP 12
130#define T_MSG_RESTART_REQ 13
131#define T_MSG_RESTART_RESP 14
132#define T_MSG_MAX 14
133
134/*
135** message parameter codes
136*/
137#define T_PARAM_MIN 1
138#define T_PARAM_PROTOCOL_LIST 1
139#define T_PARAM_PROTOCOL_SELECT 2
140#define T_PARAM_CLIENT_VERSION 3
141#define T_PARAM_OS_IDENTITY 4
142#define T_PARAM_OS_VERSION 5
143#define T_PARAM_REASON_CODE 6
144#define T_PARAM_USERNAME 7
145#define T_PARAM_REQ_PORT 8
146#define T_PARAM_RESPONSE_TEXT 9
147#define T_PARAM_STATUS_CODE 10
148#define T_PARAM_AUTH_CREDENTIALS 11
149#define T_PARAM_NONCE 12
150#define T_PARAM_SEQNUM 13
151#define T_PARAM_HASH_METHOD 14
152#define T_PARAM_LOGIN_SERVICE_PORT 15
153#define T_PARAM_LOGOUT_SERVICE_PORT 16
154#define T_PARAM_STATUS_SERVICE_PORT 17
155#define T_PARAM_SUSPEND_IND 18
156#define T_PARAM_STATUS_AUTH 19
157#define T_PARAM_RESTART_AUTH 20
158#define T_PARAM_TIMESTAMP 21
159#define T_PARAM_TSMLIST 22
160#define T_PARAM_LOGIN_PARAM_HASH 23
161#define T_PARAM_LOGIN_SERVER_HOST 24
162#define T_PARAM_MAX 24
163
164/*
165** login reason codes
166*/
167#define T_LOGIN_REASON_CODE_NORMAL 0
168#define T_LOGIN_REASON_CODE_REAUTH 1
169
170/*
171** logout reason codes
172*/
173#define T_LOGOUT_REASON_CODE_USER_INITIATED 0
174#define T_LOGOUT_REASON_CODE_APP_SHUTDOWN 1
175#define T_LOGOUT_REASON_CODE_OS_SHUTDOWN 2
176#define T_LOGOUT_REASON_CODE_UNKNOWN 3
177
178/*
179** client status transaction codes
180*/
181#define T_STATUS_TRANSACTION_OK 0
182
183/*
184** restart reasons
185*/
186#define T_RESTART_ADMIN 0
187
188/*
189** auth responses
190*/
191#define T_AUTH_NOHASH 0
192#define T_AUTH_MD5_HASH 1
193
194/*
195** protocol types
196*/
197#define T_PROTOCOL_CHAL 1
198
199/*
200** status return codes
201*/
202#define T_STATUS_SUCCESS 0
203#define T_STATUS_USERNAME_NOT_FOUND 1
204#define T_STATUS_INCORRECT_PASSWORD 2
205#define T_STATUS_ACCOUNT_DISABLED 3
206#define T_STATUS_USER_DISABLED 4
207#define T_STATUS_LOGIN_SUCCESSFUL_ALREADY_LOGGED_IN 100
208#define T_STATUS_LOGIN_RETRY_LIMIT 101
209#define T_STATUS_LOGIN_SUCCESSFUL_SWVER 102
210#define T_STATUS_LOGIN_FAIL_SW 103
211#define T_STATUS_LOGOUT_SUCCESSFUL_ALREADY_DISCONNECTED 200
212#define T_STATUS_LOGOUT_AUTH_RETRY_LIMIT 201
213#define T_STATUS_LOGIN_SUCCESS_SWVER 300
214#define T_STATUS_LOGIN_FAIL_SWVER 301
215#define T_STATUS_LOGIN_FAIL_INV_PROT 302
216#define T_STATUS_LOGIN_UNKNOWN 500
217#define T_STATUS_FAIL_USERNAME_VALIDATE 501
218#define T_STATUS_FAIL_PASSWORD_VALIDATE 502
219
220typedef unsigned short INT2;
221typedef unsigned int INT4;
222
223struct transaction
224{
225    char data[1512];
226    int length;
227};
228
229/*
230**  This structure holds all information necessary to connect/disconnect
231*/
232struct session
233{
234    /*
235    **  Control paramters
236    */
237    char username[MAXUSERNAME];
238    char password[MAXPASSWORD];
239    char authserver[MAXAUTHSERVER];
240    char authdomain[MAXAUTHDOMAIN];
241    unsigned short authport;
242    char connectedprog[MAXLOGINPROG];
243    char disconnectedprog[MAXLOGINPROG];
244    void * pUserData;
245    int shutdown;
246    char localaddress[MAXLOCALADDRESS];
247    unsigned short localport;
248    int minheartbeat, maxheartbeat;
249
250    /*
251    **  Callback functions
252    */
253    void (*debug)(int,char *,...);
254    void (*critical)(char *);
255    void (*noncritical)(char *,...);
256    void (*onconnected)(int listenport);
257    void (*ondisconnected)(int reason);
258
259    /*
260    **  Internal data
261    */
262    INT4 sessionid;
263    INT2 listenport;
264    struct sockaddr_in authhost;
265    char osname[80];
266    char osrelease[80];
267    int listensock;
268    struct sockaddr_in localaddr;
269    struct sockaddr_in localipaddress;
270
271    INT2 protocol;
272    INT2 loginserviceport;
273    char loginserverhost[128];
274    INT2 hashmethod;
275    char nonce[17];
276    INT2 retcode;
277    INT2 logoutport;
278    INT2 statusport;
279    char tsmlist[512];
280    char tsmlist_s[512][20];
281    struct sockaddr_in tsmlist_in[20];
282    int tsmcount;
283    char resptext[512];
284    INT4 timestamp;
285
286    time_t lastheartbeat;
287    int recenthb;
288    INT4 sequence;
289    struct sockaddr_in fromaddr;
290};
291
292/*
293**  Prototypes
294*/
295int mainloop(struct session *);
296int handle_heartbeats(struct session *);
297
298void start_transaction(struct transaction * t,INT2 msgtype,INT4 sessionid);
299void send_transaction(struct session *s,int socket,struct transaction * t);
300INT2 receive_transaction(struct session *s,int socket,struct transaction * t);
301INT2 receive_udp_transaction(struct session *s,int socket,struct transaction * t,struct sockaddr_in *addr);
302void send_udp_transaction(struct session * s,struct transaction * t);
303
304int  extract_valueINT2(struct session *s,struct transaction * t,INT2 parm,INT2 *v);
305int  extract_valueINT4(struct session *s,struct transaction *,INT2,INT4 *);
306int  extract_valuestring(struct session *s,struct transaction *,INT2,char *);
307
308void add_field_string(struct session *s,struct transaction * t,INT2 fn,char * p);
309void add_field_data(struct session *s,struct transaction * t,INT2 fn,char * p,int c);
310void add_field_INT2(struct session *s,struct transaction * t,INT2 fn,INT2 v);
311void add_field_INT4(struct session *s,struct transaction * t,INT2 fn,INT4 v);
312
313int  login(struct session *);
314int  logout(INT2,struct session *);
315
316INT2 read_INT2(void *);
317INT4 read_INT4(void *);
318
319void socketerror(struct session *,const char *);
320
321