{
struct passwd *pwd;
struct unixdata *data;
+ uid_t uid;
+ gid_t gid;
data = auth->mechdata;
if((pwd = getpwnam(data->username)) == NULL)
return(AUTH_ERR);
- if(sk->ucred.uid == -1) {
+ if(getucred(sk, &uid, &gid)) {
errno = EOPNOTSUPP; /* Bleh */
return(AUTH_ERR);
}
- if(pwd->pw_uid == sk->ucred.uid) {
- flog(LOG_INFO, "successful authentication as %s with Unix credentials (uid=%i, gid=%i)", data->username, sk->ucred.uid, sk->ucred.gid);
+ if(pwd->pw_uid == uid) {
+ flog(LOG_INFO, "successful authentication as %s with Unix credentials (uid=%i, gid=%i)", data->username, uid, gid);
return(AUTH_SUCCESS);
}
auth->text = swcsdup(L"Unix credentials do not match supplied user name");
static int available(struct socket *sk)
{
- return((sk->family == PF_UNIX) && (sk->ucred.uid != -1));
+ return(sockfamily(sk) == PF_UNIX);
}
static struct authmech mechdesc = {
static wchar_t *eoc, *ns, *fmt;
/* I've never understood why both of these are necessary, but... */
static wchar_t *privid, *cid;
-struct socket *udpsock, *tcpsock;
+struct socket *udpsock;
+struct lport *tcpsock;
static wchar_t **parseadc(wchar_t *cmdline)
{
sendadc(sk, 1, L"VEDolda ", ns, icsmbstowcs(VERSION, "us-ascii", NULL), NULL);
sendadc(sk, 1, L"NI", ns, fn->mynick, NULL);
sendadc(sk, 1, L"SS", ns, fmt, L"mi", (intmax_t)sharesize, L"SF", ns, fmt, L"i", sharedfiles, NULL);
- if(sk->family == AF_INET)
+ if(sockfamily(sk) == AF_INET)
sendadc(sk, 1, L"I40.0.0.0", NULL);
- else if(sk->family == AF_INET6)
+ else if(sockfamily(sk) == AF_INET6)
sendadc(sk, 1, L"I6::", NULL);
sendadc(sk, 1, L"SL", ns, fmt, L"i", confgetint("transfer", "slot"), NULL);
if(tcpsock != NULL) {
- if((sk->family == AF_INET) && !sockgetremotename(udpsock, (struct sockaddr **)&a4, &alen)) {
+ if((sockfamily(sk) == AF_INET) && !sockgetremotename(udpsock, (struct sockaddr **)&a4, &alen)) {
sendadc(sk, 1, L"U4", ns, fmt, L"i", ntohs(a4->sin_port), NULL);
free(a4);
}
flog(LOG_DEBUG, "unknown adc command: %ls", qcmd->args[0]);
}
-static void peeraccept(struct socket *sk, struct socket *newsk, void *uudata)
+static void peeraccept(struct lport *lp, struct socket *newsk, void *uudata)
{
}
struct adchub *hub;
hub = fn->data;
- hub->sk->close = 1;
+ closesock(hub->sk);
}
static int hubsetnick(struct fnetnode *fn, wchar_t *newnick)
static int updatetcpport(struct configvar *var, void *uudata)
{
struct sockaddr_in addr;
- struct socket *newsock;
+ struct lport *newsock;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
if((newsock = netcslisten(SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr), peeraccept, NULL)) == NULL)
flog(LOG_INFO, "could not listen to a remote address, going into passive mode");
if(tcpsock != NULL)
- putsock(tcpsock);
+ closelport(tcpsock);
tcpsock = newsock;
return(0);
}
static struct fnet dcnet;
static struct transferiface dctransfer;
static struct socket *udpsock = NULL;
-static struct socket *tcpsock = NULL;
+static struct lport *tcpsock = NULL;
static struct dcpeer *peers = NULL;
int numdcpeers = 0;
static struct dcexppeer *expected = NULL;
goto out;
prefix = sprintf2("$SR %s ", hub->nativenick);
infix = sprintf2(" %i/%i\005", slotsleft(), confgetint("transfer", "slots"));
- postfix = sprintf2(" (%s)\005%s|", formataddress(hub->sk->remote, hub->sk->remotelen), args + 4);
+ postfix = sprintf2(" (%s)\005%s|", formatsockpeer(hub->sk), args + 4);
dsk = sk;
getsock(dsk);
} else {
addr.sin_port = htons(atoi(p2));
prefix = sprintf2("$SR %s ", hub->nativenick);
infix = sprintf2(" %i/%i\005", slotsleft(), confgetint("transfer", "slots"));
- postfix = sprintf2(" (%s)|", formataddress(hub->sk->remote, hub->sk->remotelen));
- netdgramconn(dsk = netdupsock(udpsock), (struct sockaddr *)&addr, sizeof(addr));
+ postfix = sprintf2(" (%s)|", formatsockpeer(hub->sk));
+ dsk = netdgramconn(udpsock, (struct sockaddr *)&addr, sizeof(addr));
}
minsize = maxsize = -1;
if(tcpsock == NULL)
return;
- if(sockgetremotename2(tcpsock, sk, &addr, &addrlen) < 0)
+ if(getremotename2(tcpsock, sk, &addr, &addrlen) < 0)
return;
if(addr->sa_family == AF_INET)
qstrf(sk, "$ConnectToMe %s %s|", nick, formataddress(addr, addrlen));
{
sockpushdata(sk, peer->inbuf, peer->inbufdata);
peer->inbufdata = 0;
- transread(sk, peer);
}
} else {
/* We certainly didn't request this...*/
{
sockpushdata(sk, peer->inbuf, peer->inbufdata);
peer->inbufdata = 0;
- transread(sk, peer);
}
}
static void dcwantdata(struct transfer *transfer, struct dcpeer *peer)
{
if(transferdatasize(transfer) < 65536)
- peer->sk->ignread = 0;
+ sockblock(peer->sk, 0);
}
static void transread(struct socket *sk, struct dcpeer *peer)
return;
}
if(transferdatasize(peer->transfer) > 65535)
- sk->ignread = 1;
+ sockblock(sk, 1);
}
static void transerr(struct socket *sk, int err, struct dcpeer *peer)
size_t buflen, hashlen;
char *nick, *filename, *hubname;
struct sockaddr_in hubaddr;
+ struct sockaddr *addrbuf;
off_t size;
int slots;
struct fnetnode *fn, *myfn;
{
for(fn = fnetnodes; fn != NULL; fn = fn->next)
{
- if((fn->fnet == &dcnet) && ((hub = fn->data) != NULL))
+ if((fn->fnet == &dcnet) && ((hub = fn->data) != NULL) && !sockpeeraddr(hub->sk, &addrbuf, NULL))
{
- if((hub->sk != NULL) && addreq(hub->sk->remote, (struct sockaddr *)&hubaddr))
+ if((hub->sk != NULL) && addreq(addrbuf, (struct sockaddr *)&hubaddr))
{
myfn = fn;
break;
}
+ free(addrbuf);
}
}
}
}
memmove(hub->inbuf, p, hub->inbufdata -= p - hub->inbuf);
if(hub->queue.size > 1000)
- sk->ignread = 1;
+ sockblock(sk, 1);
}
static void huberr(struct socket *sk, int err, struct fnetnode *fn)
struct dchub *hub;
hub = (struct dchub *)fn->data;
- hub->sk->close = 1;
+ closesock(hub->sk);
}
static struct transferiface dctransfer =
break;
} else {
if(peer->queue.size > 50)
- sk->ignread = 1;
+ sockblock(sk, 1);
}
}
} else if(peer->state == PEER_TTHL) {
handletthl(peer);
}
if(peer->inbufdata > 500000)
- sk->ignread = 1;
+ sockblock(sk, 1);
}
static void peererror(struct socket *sk, int err, struct dcpeer *peer)
sendpeerlock(peer);
}
-static void peeraccept(struct socket *sk, struct socket *newsk, void *data)
+static void peeraccept(struct lport *lp, struct socket *newsk, void *data)
{
struct dcpeer *peer;
quota--;
}
if(hub->queue.size < 1000)
- hub->sk->ignread = 0;
+ sockblock(hub->sk, 0);
if(quota < 1)
break;
}
quota--;
}
if((peer->queue.size < 50) && (peer->inbufdata < 500000))
- peer->sk->ignread = 0;
+ sockblock(peer->sk, 0);
if(quota < 1)
break;
}
static int updatetcpport(struct configvar *var, void *uudata)
{
struct sockaddr_in addr;
- struct socket *newsock;
+ struct lport *newsock;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
if((newsock = netcslisten(SOCK_STREAM, (struct sockaddr *)&addr, sizeof(addr), peeraccept, NULL)) == NULL)
flog(LOG_INFO, "could not listen to a remote address, going into passive mode");
if(tcpsock != NULL)
- putsock(tcpsock);
+ closelport(tcpsock);
tcpsock = newsock;
return(0);
}
if(udpsock != NULL)
putsock(udpsock);
if(tcpsock != NULL)
- putsock(tcpsock);
+ closelport(tcpsock);
addr.sin_family = AF_INET;
memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));
addr.sin_port = htons(confgetint("dc", "udpport"));
static void transferread(struct socket *sk, struct transfer *transfer)
{
if(sockgetdatalen(sk) >= 65536)
- sk->ignread = 1;
+ sockblock(sk, 1);
if((transfer->iface != NULL) && (transfer->iface->gotdata != NULL))
transfer->iface->gotdata(transfer, transfer->ifacedata);
}
if(transfer->localend == NULL)
return(NULL);
- transfer->localend->ignread = 0;
+ sockblock(transfer->localend, 0);
time(&transfer->activity);
if((buf = sockgetinbuf(transfer->localend, size)) == NULL)
return(NULL);
transfersetsize(transfer, size);
transfer->curpos = start;
transfer->endpos = end;
- lesk->ignread = 1;
+ sockblock(lesk, 1);
transfersetlocalend(transfer, lesk);
}
transfersetstate(transfer, TRNS_MAIN);
socksettos(sk, confgetint("transfer", "ultos"));
if(transfer->localend != NULL)
- transfer->localend->ignread = 0;
+ sockblock(transfer->localend, 0);
}
void transfersetlocalend(struct transfer *transfer, struct socket *sk)
* the fd, and thus it closes it. Until I can find out whyever the
* kernel gives a POLLIN on the fd (if I can at all...), I'll just
* set ignread on insock for now. */
- insock->ignread = 1;
+ sockblock(insock, 1);
transfer->filter = pid;
transfersetlocalend(transfer, insock);
getsock(transfer->filterout = outsock);
struct uiuser *users = NULL;
struct uidata *actives = NULL;
-struct socket *tcpsocket = NULL;
-struct socket *unixsocket = NULL;
+struct lport *tcpsocket = NULL;
+struct lport *unixsocket = NULL;
static time_t starttime;
static wchar_t *quoteword(wchar_t *word)
{
int valid;
struct in6_addr mv4lo;
+ struct sockaddr *remote;
if(confgetint("ui", "onlylocal"))
{
- switch(sk->remote->sa_family)
- {
- case AF_INET:
- valid = ((struct sockaddr_in *)sk->remote)->sin_addr.s_addr == INADDR_LOOPBACK;
- break;
- case AF_INET6:
- inet_pton(AF_INET6, "::ffff:127.0.0.1", &mv4lo);
- valid = 0;
- if(!memcmp(&((struct sockaddr_in6 *)sk->remote)->sin6_addr, &in6addr_loopback, sizeof(in6addr_loopback)))
- valid = 1;
- if(!memcmp(&((struct sockaddr_in6 *)sk->remote)->sin6_addr, &mv4lo, sizeof(in6addr_loopback)))
+ valid = 0;
+ if(!sockpeeraddr(sk, &remote, NULL)) {
+ switch(remote->sa_family)
+ {
+ case AF_INET:
+ valid = ((struct sockaddr_in *)remote)->sin_addr.s_addr == INADDR_LOOPBACK;
+ break;
+ case AF_INET6:
+ inet_pton(AF_INET6, "::ffff:127.0.0.1", &mv4lo);
+ valid = 0;
+ if(!memcmp(&((struct sockaddr_in6 *)remote)->sin6_addr, &in6addr_loopback, sizeof(in6addr_loopback)))
+ valid = 1;
+ if(!memcmp(&((struct sockaddr_in6 *)remote)->sin6_addr, &mv4lo, sizeof(in6addr_loopback)))
+ valid = 1;
+ break;
+ case AF_UNIX:
valid = 1;
- break;
- case AF_UNIX:
- valid = 1;
- break;
- default:
- valid = 0;
- break;
+ break;
+ }
+ free(remote);
}
if(!valid)
{
sq(sk, 0, L"502", L"Only localhost connections allowed to this host", NULL);
- sk->close = 1;
+ closesock(sk);
data->close = 1;
return;
}
if(data->uid == -1)
{
sq(sk, 0, L"506", L"Authentication error", NULL);
- flog(LOG_INFO, "user %ls authenticated successfully from %s, but no account existed", data->username, formataddress(sk->remote, sk->remotelen));
+ flog(LOG_INFO, "user %ls authenticated successfully from %s, but no account existed", data->username, formatsockpeer(sk));
logout(data);
} else if((data->userinfo == NULL) || (data->userinfo->perms & PERM_DISALLOW)) {
sq(sk, 0, L"506", L"Authentication error", NULL);
- flog(LOG_INFO, "user %ls authenticated successfully from %s, but was not authorized", data->username, formataddress(sk->remote, sk->remotelen));
+ flog(LOG_INFO, "user %ls authenticated successfully from %s, but was not authorized", data->username, formatsockpeer(sk));
logout(data);
} else {
sq(sk, 0, L"200", L"Welcome", NULL);
- flog(LOG_INFO, "%ls (UID %i) logged in from %s", data->username, data->uid, formataddress(sk->remote, sk->remotelen));
+ flog(LOG_INFO, "%ls (UID %i) logged in from %s", data->username, data->uid, formatsockpeer(sk));
}
break;
case AUTH_DENIED:
sq(sk, 0, L"506", L"Authentication error", L"%ls", (data->auth->text == NULL)?L"":(data->auth->text), NULL);
- flog(LOG_INFO, "authentication failed for %ls from %s", data->username, formataddress(sk->remote, sk->remotelen));
+ flog(LOG_INFO, "authentication failed for %ls from %s", data->username, formatsockpeer(sk));
logout(data);
break;
case AUTH_PASS:
if(data->uid == -1)
{
sq(sk, 0, L"506", L"Authentication error", NULL);
- flog(LOG_INFO, "user %ls authenticated successfully from %s, but no account existed", data->username, formataddress(sk->remote, sk->remotelen));
+ flog(LOG_INFO, "user %ls authenticated successfully from %s, but no account existed", data->username, formatsockpeer(sk));
logout(data);
} else if((data->userinfo == NULL) || (data->userinfo->perms & PERM_DISALLOW)) {
sq(sk, 0, L"506", L"Authentication error", NULL);
- flog(LOG_INFO, "user %ls authenticated successfully from %s, but was not authorized", data->username, formataddress(sk->remote, sk->remotelen));
+ flog(LOG_INFO, "user %ls authenticated successfully from %s, but was not authorized", data->username, formatsockpeer(sk));
logout(data);
} else {
sq(sk, 0, L"200", L"Welcome", NULL);
- flog(LOG_INFO, "%ls (UID %i) logged in from %s", data->username, data->uid, formataddress(sk->remote, sk->remotelen));
+ flog(LOG_INFO, "%ls (UID %i) logged in from %s", data->username, data->uid, formatsockpeer(sk));
}
break;
case AUTH_DENIED:
sq(sk, 0, L"506", L"Authentication error", L"%ls", (data->auth->text == NULL)?L"":(data->auth->text), NULL);
- flog(LOG_INFO, "authentication failed for %ls from %s", data->username, formataddress(sk->remote, sk->remotelen));
+ flog(LOG_INFO, "authentication failed for %ls from %s", data->username, formatsockpeer(sk));
logout(data);
break;
case AUTH_PASS:
freeuidata(data);
}
-static void uiaccept(struct socket *sk, struct socket *newsk, void *data)
+static void uiaccept(struct lport *lp, struct socket *newsk, void *data)
{
struct uidata *uidata;
static int tcpportupdate(struct configvar *var, void *uudata)
{
- struct socket *newsock;
+ struct lport *newsock;
newsock = NULL;
if((var->val.num != -1) && ((newsock = netcstcplisten(var->val.num, 1, uiaccept, NULL)) == NULL))
}
if(tcpsocket != NULL)
{
- putsock(tcpsocket);
+ closelport(tcpsocket);
tcpsocket = NULL;
}
tcpsocket = newsock;
static int unixsockupdate(struct configvar *var, void *uudata)
{
- struct socket *newsock;
+ struct lport *newsock;
struct sockaddr_un *un;
mode_t ou;
umask(ou);
if(unixsocket != NULL)
{
- putsock(unixsocket);
+ closelport(unixsocket);
unixsocket = NULL;
}
unixsocket = newsock;
while(users != NULL)
freeuser(users);
if(tcpsocket != NULL)
- putsock(tcpsocket);
+ closelport(tcpsocket);
if(unixsocket != NULL)
- putsock(unixsocket);
+ closelport(unixsocket);
}
static struct configvar myvars[] =