File: session.c

package info (click to toggle)
dns2tcp 0.5.2-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,268 kB
  • sloc: ansic: 5,320; sh: 3,553; makefile: 63
file content (128 lines) | stat: -rw-r--r-- 3,599 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
** Copyright (C) 2006 Olivier DEMBOUR
** $Id: session.c,v 1.5.4.3 2010/06/02 14:38:23 collignon Exp $
**
** 
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with This program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <string.h>

#include "mycrypto.h"
#include "client.h"
#include "myerror.h"
#include "requests.h"
#include "debug.h"
#include "rr.h"
#include "myrand.h"
#include "session.h"


/**
 * @brief ask for a challenge
 * @param[in] conf configuration
 * @param[in] request request to use
 * @param[out] buffer packet received
 * @retval session id
 **/

uint16_t		request_challenge(t_conf *conf, t_request *request, char *buffer)
{
  t_packet		*packet;
  int			len;

  DPRINTF(2, "Request challenge\n");  
  if ((len = transceive_query(conf, request, buffer, MAX_DNS_LEN )) == -1)
    return (0);
  packet = (t_packet *)buffer;
  if (packet->type != OK)
    return (0);
  buffer[len] = 0;
  DPRINTF(2,"Challenge = \'%s\'\n", (char *)(packet+1));
  DPRINTF(1,"Session created (0x%x)\n", packet->session_id);
  return (packet->session_id); /* Not my challenge */
}


/**
 * @brief send the challenge response
 * @param[in] conf configuration
 * @param[out] request where to create the request
 * @param[in] challenge challenge 
 * @retval 0 on success
 * @retval -1 on error
 **/

uint8_t		send_response(t_conf *conf, t_request *request, char *challenge)
{
  char		buffer[MAX_DNS_LEN + 1];
  t_packet	*packet;
  int		len;
  
  packet = (t_packet *) &(request->u.packet);
  request->len = sign_challenge(challenge, CHALLENGE_SIZE, conf->key, (char *)(packet+1), 
				 MAX_DNS_LEN - sizeof(t_packet)) + PACKET_LEN;
  DPRINTF(2, "Sending response : '%s' (key = %s) \n",  (char *)(packet+1), conf->key)
  if ((len = transceive_query(conf, request, buffer, sizeof(buffer) -1)) == -1)
    return (-1);
  packet = (t_packet *) &buffer;
  if (packet->type == OK)
    return (0);
  return (-1);
}

/**
 * @brief try to open a session
 * @param[in] conf configuration
 * @retval 0 on error
 * @retval session id
 **/

uint16_t	create_session(t_conf *conf)
{
  char		domain[MAX_DNS_LEN + 1];
  t_request	request;
  t_packet	*packet;
  uint16_t	session_id;
  char		challenge[MAX_DNS_LEN + 1];  

  if ((strlen(conf->domain) + sizeof(AUTH)) > MAX_DNS_LEN)
    return (0);
  
  strcpy(domain, AUTH);
  strcat(domain, conf->domain);
  request.domain = (char *)&domain;
  request.type = conf->query_functions->type;
  request.request_functions = conf->query_functions;
  request.len = PACKET_LEN;
  packet = &(request.u.packet);
  packet->session_id = 0;
  packet->ack_seq = 0;
  packet->type = 0;
  packet->seq = myrand();
  if (!conf->disable_compression)
    packet->type |= USE_COMPRESS;
  if (!(session_id = request_challenge(conf, &request, (char *)&challenge)))
    return (0);
  packet->session_id = session_id;
  if (send_response(conf, &request, &challenge[PACKET_LEN]))
    {
      fprintf(stderr, "Authentication failed\n");
      return (0);
    }
  return (session_id);
}