#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip6.h>
+#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>
static void cmd_connect(struct socket *sk, struct uidata *data, int argc, wchar_t **argv)
{
int valid;
+ struct in6_addr mv4lo;
if(confgetint("ui", "onlylocal"))
{
valid = ((struct sockaddr_in *)sk->remote)->sin_addr.s_addr == INADDR_LOOPBACK;
break;
case AF_INET6:
- valid = !memcmp(&((struct sockaddr_in6 *)sk->remote)->sin6_addr, &in6addr_loopback, sizeof(in6addr_loopback));
+ 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 = 1;
break;
default:
valid = 0;
if(data->uid == -1)
{
sq(sk, 0, L"506", L"Authentication error", NULL);
- flog(LOG_INFO, "user %ls authenticated successfully, but no account existed", data->username);
+ flog(LOG_INFO, "user %ls authenticated successfully from %s, but no account existed", data->username, formataddress(sk->remote, sk->remotelen));
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, but was not authorized", data->username);
+ flog(LOG_INFO, "user %ls authenticated successfully from %s, but was not authorized", data->username, formataddress(sk->remote, sk->remotelen));
logout(data);
} else {
sq(sk, 0, L"200", L"Welcome", NULL);
- flog(LOG_INFO, "%ls (UID %i) logged in", data->username, data->uid);
+ flog(LOG_INFO, "%ls (UID %i) logged in from %s", data->username, data->uid, formataddress(sk->remote, sk->remotelen));
}
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));
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, but no account existed", data->username);
+ flog(LOG_INFO, "user %ls authenticated successfully from %s, but no account existed", data->username, formataddress(sk->remote, sk->remotelen));
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, but was not authorized", data->username);
+ flog(LOG_INFO, "user %ls authenticated successfully from %s, but was not authorized", data->username, formataddress(sk->remote, sk->remotelen));
logout(data);
} else {
sq(sk, 0, L"200", L"Welcome", NULL);
- flog(LOG_INFO, "%ls (UID %i) logged in", data->username, data->uid);
+ flog(LOG_INFO, "%ls (UID %i) logged in from %s", data->username, data->uid, formataddress(sk->remote, sk->remotelen));
}
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));
logout(data);
break;
case AUTH_PASS:
haveargs(3);
havepriv(PERM_FNETCTL);
+ for(i = 0, fn = fnetnodes; fn != NULL; i++, fn = fn->next);
+ if((confgetint("fnet", "maxnodes") > 0) && (i >= confgetint("fnet", "maxnodes"))) {
+ sq(sk, 0, L"515", L"Too many fnetnodes connected already", NULL);
+ return;
+ }
if((buf = icwcstombs(argv[2], NULL)) == NULL)
{
sq(sk, 0, L"504", L"Could not convert data to locale charset", NULL);
}
for(fn = fnetnodes; fn != NULL; fn = fn->next)
{
- sq(sk, (fn->next != NULL)?1:0, L"200", L"%%i", fn->id, fn->fnet->name, (fn->name == NULL)?L"":fn->name, L"%%i", fn->numpeers, L"%%i", fn->state, NULL);
+ sq(sk, (fn->next != NULL)?1:0, L"200", L"%%i", fn->id, fn->fnet->name, (fn->name == NULL)?L"":fn->name, L"%%i", fn->numpeers, L"%%i", fn->state, L"%%ls", fn->pubid, NULL);
}
}
for(data = actives; data != NULL; data = data->next)
{
if(haspriv(data, PERM_TRANS) && data->notify.b.tract && ((transfer->owner == 0) || (transfer->owner == data->uid)))
- newnotif(data, 617, NOTIF_ID, transfer->id, NOTIF_END);
+ newnotif(data, 617, NOTIF_ID, transfer->id, NOTIF_STR, (transfer->exitstatus == NULL)?L"":(transfer->exitstatus), NOTIF_END);
}
return(0);
}
}
}
-#ifdef HAVE_IPV6
-static struct sockaddr *getnameforport(int port, socklen_t *len)
-{
- static struct sockaddr_in6 addr;
-
- memset(&addr, 0, sizeof(addr));
- addr.sin6_family = AF_INET6;
- addr.sin6_port = htons(port);
- addr.sin6_addr = in6addr_any;
- if(len != NULL)
- *len = sizeof(addr);
- return((struct sockaddr *)&addr);
-}
-#else
-static struct sockaddr *getnameforport(int port, socklen_t *len)
-{
- static struct sockaddr_in addr;
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- if(len != NULL)
- *len = sizeof(addr);
- return((struct sockaddr *)&addr);
-}
-#endif
-
static int portupdate(struct configvar *var, void *uudata)
{
- struct sockaddr *addr;
- socklen_t addrlen;
struct socket *newsock;
- addr = getnameforport(var->val.num, &addrlen);
- if((uisocket = netcslistenlocal(SOCK_STREAM, addr, addrlen, uiaccept, NULL)) == NULL)
+ if((uisocket = netcstcplisten(var->val.num, 1, uiaccept, NULL)) == NULL)
{
flog(LOG_WARNING, "could not create new UI socket, reverting to old: %s", strerror(errno));
return(0);
static int init(int hup)
{
- struct sockaddr *addr;
- socklen_t addrlen;
struct uiuser *user, *next;
if(hup)
{
if(uisocket != NULL)
putsock(uisocket);
- addr = getnameforport(confgetint("ui", "port"), &addrlen);
- if((uisocket = netcslistenlocal(SOCK_STREAM, addr, addrlen, uiaccept, NULL)) == NULL)
+ if((uisocket = netcstcplisten(confgetint("ui", "port"), 1, uiaccept, NULL)) == NULL)
{
flog(LOG_CRIT, "could not create UI socket: %s", strerror(errno));
return(1);