• Jueves 28 de Marzo de 2024, 23:05

Autor Tema:  Un Error Que No Consigo Solucionar  (Leído 2633 veces)

edurne

  • Miembro activo
  • **
  • Mensajes: 35
    • Ver Perfil
Un Error Que No Consigo Solucionar
« en: Viernes 1 de Abril de 2005, 10:31 »
0
Hola de nuevo. Volví a perfeccionar mi servidor, y todo marcha bien, salvo un error que no entiendo. El programa funciona correctamente, si meto los datos correctos, almacena lo que deseo, si meto datos incorrectos, intenta comprobarlos 5 veces hasta que finalmente me da el mensaje de fallo.
Sin embargo, haga lo que haga, siempre sale en la pantalla del servidor el siguiente mensaje:

Traceback (most recent call last):
  File "./servidorcompleto.py", line 250, in ?
    server = SocketServer.TCPServer(('khaos',port), BaseRequestHandler)
  File "/usr/lib/python2.1/SocketServer.py", line 329, in __init__
    self.server_bind()
  File "/usr/lib/python2.1/SocketServer.py", line 340, in server_bind
    self.socket.bind(self.server_address)
socket.error: (98, 'Address already in use')                                                                                                      



Éste es mi servidor:




#!/usr/bin/python

from pyPgSQL import PgSQL
import SocketServer
import sys, os, string
from syslog import *
import md5
import whrandom
import time

def conectar_db():
   global cnx
   try:
      #syslog(LOG_DEBUG,'\nConectando a la base de datos...')
      cnx = PgSQL.connect(user ='kemdb', host ='khaos', database ='smtu')
      syslog(LOG_DEBUG,'\nConectado a la base de datos, comprobando datos recibidos...')
   except PgSQL.Error:
      sys.exit(1)

def crear_configuracion():
   conf = '%c%c%c%c%c' %(3,5,0x23,0xc2,5)
   return conf

def crear_challenge():
   id = whrandom.randint(0,255)
   syslog(LOG_INFO,'id_cliente:'+str(id))
   a = whrandom.randint(0, 255)
   syslog(LOG_INFO, 'challenge_value=a:'+str(a))
   challenge_value = '%c%c%c%c%c%c' % (whrandom.randint(0, 255),whrandom.randint(0, 255),whrandom.randint(0, 255),whrandom.randint(0, 255),whrandom.randint(0, 255),whrandom.randint(0, 255))
   len_cha = len(challenge_value)
   value_size =1
   name = 'mrpfd'
   len_name = len(name)
   length =11+len_name
   lengthb = length >> 8
   challenge = '%c%c%c%c%c' % (1,id,length,lengthb,len_cha)
   challenge += challenge_value+name
   return challenge
   #print 'identidad:', challenge[1:2]
   #print 'challenge_value:', challenge[5:11]

def analizar_nombre_response(cursor, response, error_com):
   global nombre
   nombre = response[21:]
   #print 'nombre recibido de la respuesta: ', nombre
   query="select * from idip where nombre='" + nombre + "'"
   syslog(LOG_DEBUG,query)
   try:
      cursor.execute(query)
   except PgSQL.Error:
      error_com =1
      syslog(LOG_ERR,'error al buscar usuario en base de datos')
      #sys.exit()
   dat = cursor.fetchall()
   #syslog(LOG_DEBUG,'\nLocalizando datos...')
   n = 0
   for elemento in dat:
      n = n+1
   if n >= 2:
      duplicado = 1
      error_com = 0
      datos = 'duplicado'
      return (duplicado, datos, error_com)
   elif n == 0:
      duplicado = 0
      error_com = 0
      datos  =  ''
      return (duplicado, datos, error_com)
   else:
      duplicado = 0
      error_com = 0
      dato= dat[0]
      datos = dato[0]
      return (duplicado, datos, error_com)

def localizar_nombre_db(datos):
   if datos == '':
      syslog(LOG_ERR,'\nNo se encuentra en la base de datos ')
      encontrado = 0
      return encontrado
   else:
      syslog(LOG_DEBUG,'\nLocalizado en la base de datos')
      encontrado = 1
      return encontrado

def buscar_contrasena(datos, cursor, error_com):
   query = "select password from idip where nombre='" + datos + "'"
   #syslog(LOG_DEBUG,query)
   try:
      cursor.execute(query)
   except PgSQL.Error:
      #sys.exit()
      syslog(LOG_ERR,'\nError al buscar la contrasea')
      error_comunicacion = 1
   contr = cursor.fetchall()
   #print contr
   contras = contr[0]
   return (contras[0], error_com)

def comprobar_encriptamientos(response, password):
   response_value = response[5:21]
   cadena = challenge[1]+password+challenge[5:11]
   #print 'cadena a la que voy a aplicar yo el md5 formada por id+passw de la db+challengevalue: ', cadena
   value = md5.new(challenge[1]+password+challenge[5:11]).digest()
   hexvalue = md5.new()
   hexvalue.update(challenge[1]+password+challenge[5:11])
   imprimir = hexvalue.hexdigest()
   syslog(LOG_INFO,imprimir)
   if value == response_value:
      exito = 1
      syslog(LOG_DEBUG,'\nSuccess')
   else:
      exito = 0
      syslog(LOG_DEBUG,'\nFailure')
   return  exito

def funcion_success(response):
   success = '%c'  % (3)+ response[1]+ '%c%c' % (0x18, 0x00)+ 'success'
   #print success
   return success

def funcion_failure(response):
   failure = '%c'  % (4)+ response[1]+ '%c%c' % (0x1b, 0x00) + 'failure'
   #print failure
   return failure

def almacenar_ip_date_validez(self, cursor, nombre, password, error_com):
   dirip = string.split(self.client_address[0], '.')
   ip = string.atoi(dirip[0])
   ip  <<= 8
   ip |= string.atoi(dirip[1])
   ip <<= 8
   ip |= string.atoi(dirip[2])
   ip <<= 8
   ip |= string.atoi(dirip[3])
   syslog(LOG_INFO, 'ip en su valor verdadero es: %x' %ip)
   strip = str(ip)
   strvalidez = str(1)
   query ="update idip set ip ='" + strip + "'where nombre='" + nombre + "'and password='" + password + "'"
   #syslog(LOG_DEBUG, query)
   error = 0
   try:
      cursor.execute(query)
   except PgSQL.Error:
      syslog(LOG_ERR,'\nError al actualizar  ip')
      #sys.exit()
      error_com = 1
   query = "update idip set date ='" + time.asctime() + "'where nombre='" + nombre + "'and password='" + password + "'"
   #syslog(LOG_DEBUG, query)
   error = 0
   try:
      cursor.execute(query)
   except PgSQL.Error:
      syslog(LOG_ERR, '\nError al  actualizar la fecha')
      #sys.exit()
      error_com =1
   query = "update idip set validez ='" + strvalidez + "'where nombre='" + nombre + "'and password='" + password + "'"
   #syslog(LOG_DEBUG, query)
   try:
      cursor.execute(query)
   except PgSQL.Error:
      syslog(LOG_ERR, '\nError al actualizar la validez')
      #sys.exit()
      error_com = 1
   query = "select * from idip where nombre='" + nombre + "' and password ='" + password + "'"
   #syslog(LOG_DEBUG, query)
   error = 0
   try:
      cursor.execute(query)
   except PgSQL.Error:            
      syslog(LOG_ERR, '\nError al visualizar los datos')
      #sys.exit()
      error_com =1
   datos = cursor.fetchall()
   syslog(LOG_INFO, '\nLos datos introducidos son: '+str(datos))
   return error_com

def desconectar (cursor, cnx):
   cursor.close()
   cnx.commit()
   cnx.close()
   syslog(LOG_DEBUG, '\nDesconectado de la DB')

def chap_simple(self):
   global cursor
   global response
   global challenge
   global conf
   conf = crear_configuracion()
   self.request.send(conf)
   challenge = crear_challenge()
   self.request.send(challenge)
   response = self.request.recv(1024)
   cursor = cnx.cursor()
   error_comunicacion = 0
   cuenta_errores = 1
   while cuenta_errores !=0 and cuenta_errores <6:
      duplicado, datos, error_comunicacion = analizar_nombre_response(cursor, response, error_comunicacion)
      #print 'datos, o nombre a buscar en la db:', datos
      #print 'error de comunicacin antes de ver duplicado:', error_comunicacion
      if error_comunicacion == 0:
         if duplicado == 1:
            syslog(LOG_ERR, '\nSe ha encotrado a ms de un usuario con el mismo nombre.')
            #self.request.send('\nError')
            error_comunicacion = 1
            cuenta_errores = cuenta_errores +1
         else:
            encontrado = localizar_nombre_db(datos)
            if encontrado ==1:
               password, error_comunicacion = buscar_contrasena(datos, cursor, error_comunicacion)
               if error_comunicacion == 0:
                  if password == []:
                     syslog(LOG_ERR, '\nHa habido algn error al tomar el password')
                     error_comunicacion = 1
                     cuenta_errores = cuenta_errores +1
                  else:
                     exito = comprobar_encriptamientos(response, password)
                     if exito ==1:
                        success = funcion_success(response)
                        self.request.send(success)
                        error_comunicacion = almacenar_ip_date_validez(self, cursor, nombre, password, error_comunicacion)
                        syslog(LOG_DEBUG, ' actualizando ip, fecha y validez...')
                        if error_comunicacion == 0:
                           cuenta_errores = 0
                        else:
                           cuenta_errores = cuenta_errores +1
                     else:
                        cuenta_errores = cuenta_errores +1
               else: cuenta_errores = cuenta_errores +1
            else:
               cuenta_errores = cuenta_errores + 1
               #self.request.send('\nError, no localizado en la base de datos')
      else: cuenta_errores = cuenta_errores +1
      print "cuenta_err = ",cuenta_errores,"\n"
      if cuenta_errores == 6 or cuenta_errores == 0:
         failure = funcion_failure(response)
         self.request.send(failure)
         desconectar(cursor, cnx)
      else: pass

class BaseRequestHandler(SocketServer.BaseRequestHandler):
   def handle(self):
      conectar_db()
      chap_simple (self)
      #if cuenta_errores == 0: break
while 1:
   puerto = sys.argv[1]
   port = int(puerto)
   #print "argv[1]=",puerto,"\n"
   server = SocketServer.TCPServer(('',port), BaseRequestHandler)
   #server.BaseRequestHandler
   #server.handle_request()
   server.serve_forever()







y éste es mi cliente:




#!/usr/bin/python
from pyPgSQL import PgSQL
import SocketServer
import sys, os, string
import md5
import whrandom
import socket
def comprobar_nombre_contrasena(so, cuenta_errores):
   while cuenta_errores !=0 and cuenta_errores <6:
      nombre = raw_input('Usuario:')
      contrasena = raw_input('Contrasea:')
      if len(nombre)>20 or len(contrasena)>20 or nombre == '' or contrasena == '':
         cuenta_errores = cuenta_errores + 1
      else:
         for letra in nombre:
            error_nombre = 0
            if letra in string.uppercase or letra in string.digits: pass
            else: error_nombre = error_nombre +1
         for nuevaletra in contrasena:
            error_contrasena = 0
            if nuevaletra in string.uppercase or nuevaletra in string.digits: pass
            else: error_contrasena = error_contrasena +1
         if error_nombre == 0 and error_contrasena == 0 : cuenta_errores = 0
         else: cuenta_errores = cuenta_errores +1
   return (cuenta_errores, nombre, contrasena)
def crear_response(so, contrasena, nombre, challenge):
   response_length=21+len(nombre)
   response_lengthb=response_length>>8
   if response_length > 65535:
      #print '\nError'
      so.close()
   else:
      id = challenge[1]
      #print 'id recibida del challenge: ', challenge[1:2]
      cadena=challenge[1]+contrasena+challenge[5:11]
      #print 'cadena para hacer en md5 de la respuesta formada por: id+contrasea+challengevalue: ', cadena
      value=md5.new(challenge[1]+contrasena+challenge[5:11]).digest()
      hexvalue=md5.new()
      hexvalue.update(challenge[1]+contrasena+challenge[5:11])
      imprimir = hexvalue.hexdigest()
      response = '%c%c%c%c%c' %(2, id, response_length, response_lengthb, 16) + value + nombre
      return response
puerto = raw_input('Puerto:')
port = int(puerto)
so = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
so.connect (('', port))
configuration = so.recv(2048)
challenge = so.recv(2048)
cuenta_errores = 1
error = 1
cuenta_errores, nombre, contrasena = comprobar_nombre_contrasena(so, cuenta_errores)
if cuenta_errores == 0:
   response = crear_response(so, contrasena, nombre,  challenge)
   #print 'response mandada formada por: code+id+long+valuesize+value+name: ', response
so.send(response)
resultado = so.recv(1024)
code = ord(resultado[0])
if code == 3: print 'success'
elif code == 4: print 'failure'
else: print 'fallo al recibir estado'
so.close()




Si alguien me puede ayudar me sería muy útil. Gracias!!
Saludos, Edurne

edurne

  • Miembro activo
  • **
  • Mensajes: 35
    • Ver Perfil
Re: Un Error Que No Consigo Solucionar
« Respuesta #1 en: Viernes 1 de Abril de 2005, 11:46 »
0
Ya he encontrado el problema. Lo primero, aclarar que el programa qwue había puesto no era el correcto. Mi problema era que había puesto un bucle while 1 en mi programa principal con un server.handle_request, y el bucle daba error. Ha bastadio con quitar el bucle.

NRM

  • Miembro MUY activo
  • ***
  • Mensajes: 279
  • Nacionalidad: ar
    • Ver Perfil
    • http://www.narrowmind.com.ar
Re: Un Error Que No Consigo Solucionar
« Respuesta #2 en: Viernes 1 de Abril de 2005, 16:17 »
0
El problema parece ser que estas tratando de abrir un puerto que ya esta en uso. Deberias chequear que puerto estas tratando de abir.

Saludos