Logo Search packages:      
Sourcecode: gaim-librvp version File versions  Download package

rvp.h

/*
 *  File: rvp.h - Gaim RVP plug-in implementation.
 *  Copyright (C) 2003  Weihua Sun (weihua@lucent.com)
 *
 *  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
 */

#ifndef _RVP_H_
#define _RVP_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <libxml/parser.h>

#include "config.h"
#include "gaim.h"
#include "prpl.h"
#include "proxy.h"
#include "random.h"

#define PROTO_RVP "prpl-rvp"

#define RVP_BUF_SIZE    1024

/*---------------------------------
 * RVP status
 *--------------------------------*/

typedef enum _rvp_status {
  RVP_ONLINE = 1,
  RVP_BUSY,
  RVP_IDLE,
  RVP_BRB,
  RVP_AWAY,
  RVP_PHONE,
  RVP_LUNCH,
  RVP_OFFLINE,
  RVP_HIDDEN,
  RVP_UNKNOWN,
} RVPStatus;

/* this is for our list of away states */
typedef struct _away_t {
  gchar *tag;
  gchar *text;
} away_t;

#define RVP_PORT 80
#define RVP_VIEW_TIME 1200
#define RVP_SUBS_TIME 14000

#define EXCHANGE_TYPING_TIMEOUT 4

/* this is entirely arbitrary */
#define MAX_LOGIN_STEPS 5

/* this is what I should be using instead of the above */
#define RVP_LOGIN_SUBSCRIBE     0x01
#define RVP_LOGIN_PROPPATCH     0x02
#define RVP_LOGIN_PROPFIND      0x04
#define RVP_LOGIN_SUBSCRIPTIONS 0x08
#define RVP_LOGIN_ACL           0x10
#define RVP_LOGIN_ALL           (RVP_LOGIN_ACL|RVP_LOGIN_SUBSCRIPTIONS|RVP_LOGIN_PROPFIND|RVP_LOGIN_PROPPATCH|RVP_LOGIN_SUBSCRIBE)

/* Known GUIDs (unofficial, taken from packet traces */
/* the braces are left in place to make my life easier */
#define RVP_GUID_FILE_TRANSFER "{5D3E02AB-6190-11d3-BBBB-00C04F795683}"
#define RVP_GUID_APP_SHARING   "{F1B1920C-6A3C-4ce7-B18C-AFAB305FD03D}"
#define RVP_GUID_WHITEBOARD    "{1DF57D09-637A-4ca5-91B9-2C3EDAAF62FE}"

/* types of authorisation we understand. the official client seems to
   only do NTLM */
enum rvp_auth_type {
  RVP_AUTH_NONE = 0,
  RVP_AUTH_NTLM,
  RVP_AUTH_DIGEST,
};

/* message types */
enum rvp_message_type {
  RVP_MSG_IM = 0,
  RVP_MSG_TYPING,
  RVP_MSG_INVITE,
  RVP_MSG_CHAT_INVITE,
  RVP_MSG_CHAT,
  RVP_MSG_CHAT_LEAVE,
  RVP_MSG_UNKNOWN,
};

/* RVP_MSG_INVITE subtypes */
enum rvp_invite_type {
  RVP_INV_INVITE = 0,
  RVP_INV_ACCEPT,
  RVP_INV_CANCEL,
  RVP_INV_UNKNOWN,
};

/* handy structure for hashing invites */
typedef struct _invite {
  enum rvp_invite_type type;
  gint cookie;
  gint authcookie;
  gchar *who; /* so we can use server_alias in xfer messages */
  gint sock;
  gint sockx;
  gint xfersock;
  int inp;
  int inpx;
  int xferinp;

  /* these are used for temp storage during the handshake */
  gchar hdr[3];
  gint hdrread;
  gint inbuflen;
  gchar *inbuffer;
  gint outbuflen;
  gchar *outbuffer;

  /* keep track of how much of current block we've got */
  gint blocksize;
  gint blockgot;

  /* points at the GaimXfer structure */
  gpointer data;
} RVPInvite;

/* DNS service record */
typedef struct _srvrec {
  /* realistically this should be a list of
     { host, port, priority, weight } structures */
  char *host;
  int port;
  time_t expiry; /* time at which we'll need to requery */
} srvrec;

/* credentials */
#define RVP_ACL_CREDENTIALS       0xf000
#define RVP_ACL_ASSERTION         0x1000
#define RVP_ACL_DIGEST            0x2000
#define RVP_ACL_NTLM              0x4000

/* permissions */
#define RVP_ACL_ALL               0x0fff
#define RVP_ACL_LIST              0x0001
#define RVP_ACL_READ              0x0002
#define RVP_ACL_WRITE             0x0004
#define RVP_ACL_SEND_TO           0x0008
#define RVP_ACL_RECEIVE_FROM      0x0010
#define RVP_ACL_READACL           0x0020
#define RVP_ACL_WRITEACL          0x0040
#define RVP_ACL_PRESENCE          0x0080
#define RVP_ACL_SUBSCRIPTIONS     0x0100
#define RVP_ACL_SUBSCRIBE_OTHERS  0x0200
#define RVP_ACL_BUDDY             (RVP_ACL_SEND_TO | RVP_ACL_PRESENCE)

/*
 * Mappings used:
 * GaimBuddy->name is user@imhost.domain.com
 * GaimBuddy->server_alias is <displayname> property
 */
typedef struct rvp_buddy {
  GaimBuddy *buddy;     /* the buddylist node that owns this */
  gchar *principal;     /* http://..../instmsg/aliases/username */
  gchar *sessionid;     /* conversation tracker */
  gint   subs_id;       /* the other conversation tracker */
  time_t expires;       /* when this subscription expires */

  /* things propfind tells us [displayname goes into server_alias] */
  gchar *email;
  gint mobile_state;
  gchar *mobile_description;
  gchar *state;

  /* this should be cached separately, I'm sure */
  srvrec *service;

  /* bitfield */
  guint16 acl;

  GHashTable *sendcookies;  /* file transfer &c. cookies */
  GHashTable *recvcookies;
} RVPBuddy;

typedef struct rvp_data {
  RVPBuddy me; /* everyone should be their own buddy! */

  /* deprecating the 'me' variable */
  gchar *principal;
  srvrec *service;
  time_t subs_expiry;

  gint subs_id; /* different from me.subs_id */

  gint login_step;                    /* how far through login we've */
  gint login_flags;                   /*   gotten */
  enum rvp_auth_type auth_type;       /* type of auth mechanism */
  gint view_id;                       /* Client view id */
  time_t view_expiry;                 /* expiry time for view id */

  GHashTable *nonbuddy;               /* track non-buddy conversations */
  GHashTable *chats;                  /* list of chats */
  gint chatid;                        /* last-used chat id */

  /* keep track of requests */
  GHashTable *pending;

  /* listener data */
  int listener_fd;                    /* filehandle of listener */
  int listener_port;                  /* port of same */
  int port_low;                       /* range of ports we listen on */
  int port_high;                      /* - set to zero for 'all ports' */

  guint16 defaultacl;                 /* allprincipal acl setting */

  gchar *authdomain;                  /* IM server internet domain */
  gchar *authhost;                    /* IM server host */
  int port;                           /* IM server port */
  gchar *client_host;                 /* my name, for use in callbacks */

  /* everything below here needs to get verified */

  int inpa;
  int linpa;

  /* session data */
  char *domain;       /* IM server domain */
  char *authid;       /* auth id */
  char *session_id;   /* Client session id */
} RVPData;

char *get_auth_ntlm(char *www_authenticate, char *username,
                    char *passwd, char *hostname, char *domain, char *authid);
char *get_ntlm_msg1( char *domain, char *host );

typedef struct _GaimFetchUrlData {
  void (*callback)(void *, struct _GaimFetchUrlData *, size_t);
  void *user_data;

  gboolean tried_auth;

  struct {
    char *user;
    char *passwd;
    char *address;
    int port;
    char *page;

  } website;

  char *method;
  char *url;
  gboolean full;

  gint sock;

  int inpa;
  guint timeout;

  gboolean sentreq;
  gboolean newline;
  gboolean startsaving;
  gboolean has_explicit_data_len;
  gboolean encoded;
  gboolean resend;
  gboolean preserve;

  struct {
    char *header;
    char *webdata;
    int length;
  } request;
  struct {
    char *header;
    char *webdata;
  } response;
  unsigned long len;
  unsigned long data_len;

  GHashTable *parsedheaders;

  /* allow buffering of write */
  gchar *buf;
  guint *bufsize;
  guint *bufsent;

  /* this is awful, but saves me a lot of work */
  gchar *message;
} GaimFetchUrlData;

/* we shouldn't really have a gtk function in here, but it's
   unavoidable since Gaim doesn't seem to provide a hook to the main
   event loop otherwise. */
#ifdef LOUD
time_t last_report;

#define zero_time last_report = time( NULL )
#define report_sent(x) \
  if ( time( NULL ) != last_report ) { \
    gaim_debug_misc( __FUNCTION__, "sending %p\n", x ); \
    last_report = time( NULL ); \
  }
#define report_free(x) \
  if ( time( NULL ) != last_report ) { \
    gaim_debug_misc( __FUNCTION__, "waiting %p\n", x ); \
    last_report = time( NULL ); \
  }

#else
#define zero_time
#define report_sent(x)
#define report_free(x)
#endif

#define RVP_LOOP_UNTIL_FREE( x ) \
  zero_time; \
  while( g_hash_table_lookup( rd->pending, x )) {   \
    while( gtk_events_pending()) {                  \
      report_free(x)                                \
        gtk_main_iteration();                       \
    }                                               \
  }

#endif /* _RVP_H_ */

Generated by  Doxygen 1.6.0   Back to index