int getCharSize() { FILE *f; Str tmp; int w = 0, h = 0; set_environ("W3M_TTY", ttyname_tty()); tmp = Strnew(); if (!strchr(Imgdisplay, '/')) Strcat_m_charp(tmp, w3m_auxbin_dir(), "/", NULL); Strcat_m_charp(tmp, Imgdisplay, " -test 2>/dev/null", NULL); f = popen(tmp->ptr, "r"); if (!f) return FALSE; while (fscanf(f, "%d %d", &w, &h) < 0) { if (feof(f)) break; } pclose(f); if (!(w > 0 && h > 0)) return FALSE; if (!set_pixel_per_char) pixel_per_char = (int)(1.0 * w / COLS + 0.5); if (!set_pixel_per_line) pixel_per_line = (int)(1.0 * h / LINES + 0.5); return TRUE; }
char * form2str(FormItemList *fi) { Str tmp = Strnew(); if (fi->type != FORM_SELECT && fi->type != FORM_TEXTAREA) Strcat_charp(tmp, "input type="); Strcat_charp(tmp, _formtypetbl[fi->type]); if (fi->name && fi->name->length) Strcat_m_charp(tmp, " name=\"", fi->name->ptr, "\"", NULL); if ((fi->type == FORM_INPUT_RADIO || fi->type == FORM_INPUT_CHECKBOX || fi->type == FORM_SELECT) && fi->value) Strcat_m_charp(tmp, " value=\"", fi->value->ptr, "\"", NULL); Strcat_m_charp(tmp, " (", _formmethodtbl[fi->parent->method], " ", fi->parent->action->ptr, ")", NULL); return tmp->ptr; }
Buffer * follow_map_panel(Buffer *buf, char *name) { Str mappage; MapList *ml; ListItem *al; MapArea *a; ParsedURL pu; char *p, *q; Buffer *newbuf; ml = searchMapList(buf, name); if (ml == NULL) return NULL; mappage = Strnew_charp(map1); for (al = ml->area->first; al != NULL; al = al->next) { a = (MapArea *) al->ptr; if (!a) continue; parseURL2(a->url, &pu, baseURL(buf)); p = parsedURL2Str(&pu)->ptr; q = html_quote(p); if (DecodeURL) p = html_quote(url_unquote_conv(p, buf->document_charset)); else p = q; Strcat_m_charp(mappage, "<tr valign=top><td><a href=\"", q, "\">", html_quote(*a->alt ? a->alt : mybasename(a->url)), "</a><td>", p, NULL); } Strcat_charp(mappage, "</table></body></html>"); newbuf = loadHTMLString(mappage); #ifdef USE_M17N if (newbuf) newbuf->document_charset = buf->document_charset; #endif return newbuf; }
Str ssl_get_certificate(SSL * ssl, char *hostname) { BIO *bp; X509 *x; X509_NAME *xn; char *p; int len; Str s; char buf[2048]; Str amsg = NULL; Str emsg; char *ans; if (ssl == NULL) return NULL; x = SSL_get_peer_certificate(ssl); if (x == NULL) { if (accept_this_site && strcasecmp(accept_this_site->ptr, hostname) == 0) ans = "y"; else { /* FIXME: gettextize? */ emsg = Strnew_charp("No SSL peer certificate: accept? (y/n)"); ans = inputAnswer(emsg->ptr); } if (ans && TOLOWER(*ans) == 'y') /* FIXME: gettextize? */ amsg = Strnew_charp ("Accept SSL session without any peer certificate"); else { /* FIXME: gettextize? */ char *e = "This SSL session was rejected " "to prevent security violation: no peer certificate"; disp_err_message(e, FALSE); free_ssl_ctx(); return NULL; } if (amsg) disp_err_message(amsg->ptr, FALSE); ssl_accept_this_site(hostname); /* FIXME: gettextize? */ s = amsg ? amsg : Strnew_charp("valid certificate"); return s; } #ifdef USE_SSL_VERIFY /* check the cert chain. * The chain length is automatically checked by OpenSSL when we * set the verify depth in the ctx. */ if (ssl_verify_server) { long verr; if ((verr = SSL_get_verify_result(ssl)) != X509_V_OK) { const char *em = X509_verify_cert_error_string(verr); if (accept_this_site && strcasecmp(accept_this_site->ptr, hostname) == 0) ans = "y"; else { /* FIXME: gettextize? */ emsg = Sprintf("%s: accept? (y/n)", em); ans = inputAnswer(emsg->ptr); } if (ans && TOLOWER(*ans) == 'y') { /* FIXME: gettextize? */ amsg = Sprintf("Accept unsecure SSL session: " "unverified: %s", em); } else { /* FIXME: gettextize? */ char *e = Sprintf("This SSL session was rejected: %s", em)->ptr; disp_err_message(e, FALSE); free_ssl_ctx(); return NULL; } } } #endif emsg = ssl_check_cert_ident(x, hostname); if (emsg != NULL) { if (accept_this_site && strcasecmp(accept_this_site->ptr, hostname) == 0) ans = "y"; else { Str ep = Strdup(emsg); if (ep->length > COLS - 16) Strshrink(ep, ep->length - (COLS - 16)); Strcat_charp(ep, ": accept? (y/n)"); ans = inputAnswer(ep->ptr); } if (ans && TOLOWER(*ans) == 'y') { /* FIXME: gettextize? */ amsg = Strnew_charp("Accept unsecure SSL session:"); Strcat(amsg, emsg); } else { /* FIXME: gettextize? */ char *e = "This SSL session was rejected " "to prevent security violation"; disp_err_message(e, FALSE); free_ssl_ctx(); return NULL; } } if (amsg) disp_err_message(amsg->ptr, FALSE); ssl_accept_this_site(hostname); /* FIXME: gettextize? */ s = amsg ? amsg : Strnew_charp("valid certificate"); Strcat_charp(s, "\n"); xn = X509_get_subject_name(x); if (X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf)) == -1) Strcat_charp(s, " subject=<unknown>"); else Strcat_m_charp(s, " subject=", buf, NULL); xn = X509_get_issuer_name(x); if (X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf)) == -1) Strcat_charp(s, ": issuer=<unknown>"); else Strcat_m_charp(s, ": issuer=", buf, NULL); Strcat_charp(s, "\n\n"); bp = BIO_new(BIO_s_mem()); X509_print(bp, x); len = (int)BIO_ctrl(bp, BIO_CTRL_INFO, 0, (char *)&p); Strcat_charp_n(s, p, len); BIO_free_all(bp); X509_free(x); return s; }
static Str ssl_check_cert_ident(X509 * x, char *hostname) { int i; Str ret = NULL; int match_ident = FALSE; /* * All we need to do here is check that the CN matches. * * From RFC2818 3.1 Server Identity: * If a subjectAltName extension of type dNSName is present, that MUST * be used as the identity. Otherwise, the (most specific) Common Name * field in the Subject field of the certificate MUST be used. Although * the use of the Common Name is existing practice, it is deprecated and * Certification Authorities are encouraged to use the dNSName instead. */ i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1); if (i >= 0) { X509_EXTENSION *ex; STACK_OF(GENERAL_NAME) * alt; ex = X509_get_ext(x, i); alt = X509V3_EXT_d2i(ex); if (alt) { int n; GENERAL_NAME *gn; X509V3_EXT_METHOD *method; Str seen_dnsname = NULL; n = sk_GENERAL_NAME_num(alt); for (i = 0; i < n; i++) { gn = sk_GENERAL_NAME_value(alt, i); if (gn->type == GEN_DNS) { char *sn = ASN1_STRING_data(gn->d.ia5); int sl = ASN1_STRING_length(gn->d.ia5); if (!seen_dnsname) seen_dnsname = Strnew(); /* replace \0 to make full string visible to user */ if (sl != strlen(sn)) { int i; for (i = 0; i < sl; ++i) { if (!sn[i]) sn[i] = '!'; } } Strcat_m_charp(seen_dnsname, sn, " ", NULL); if (sl == strlen(sn) /* catch \0 in SAN */ && ssl_match_cert_ident(sn, sl, hostname)) break; } } method = X509V3_EXT_get(ex); sk_GENERAL_NAME_free(alt); if (i < n) /* Found a match */ match_ident = TRUE; else if (seen_dnsname) /* FIXME: gettextize? */ ret = Sprintf("Bad cert ident from %s: dNSName=%s", hostname, seen_dnsname->ptr); } } if (match_ident == FALSE && ret == NULL) { X509_NAME *xn; char buf[2048]; int slen; xn = X509_get_subject_name(x); slen = X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf)); if ( slen == -1) /* FIXME: gettextize? */ ret = Strnew_charp("Unable to get common name from peer cert"); else if (slen != strlen(buf) || !ssl_match_cert_ident(buf, strlen(buf), hostname)) { /* replace \0 to make full string visible to user */ if (slen != strlen(buf)) { int i; for (i = 0; i < slen; ++i) { if (!buf[i]) buf[i] = '!'; } } /* FIXME: gettextize? */ ret = Sprintf("Bad cert ident %s from %s", buf, hostname); } else match_ident = TRUE; } return ret; }
Buffer * load_option_panel(void) { Str src; struct param_ptr *p; struct sel_c *s; #ifdef USE_M17N wc_ces_list *c; #endif int x, i; Str tmp; Buffer *buf; if (optionpanel_str == NULL) optionpanel_str = Sprintf(optionpanel_src1, w3m_version, html_quote(localCookie()->ptr), _(CMT_HELPER)); #ifdef USE_M17N #ifdef ENABLE_NLS OptionCharset = SystemCharset; /* FIXME */ #endif if (!OptionEncode) { optionpanel_str = wc_Str_conv(optionpanel_str, OptionCharset, InnerCharset); for (i = 0; sections[i].name != NULL; i++) { sections[i].name = wc_conv(_(sections[i].name), OptionCharset, InnerCharset)->ptr; for (p = sections[i].params; p->name; p++) { p->comment = wc_conv(_(p->comment), OptionCharset, InnerCharset)->ptr; if (p->inputtype == PI_SEL_C #ifdef USE_COLOR && p->select != colorstr #endif ) { for (s = (struct sel_c *)p->select; s->text != NULL; s++) { s->text = wc_conv(_(s->text), OptionCharset, InnerCharset)->ptr; } } } } #ifdef USE_COLOR for (s = colorstr; s->text; s++) s->text = wc_conv(_(s->text), OptionCharset, InnerCharset)->ptr; #endif OptionEncode = TRUE; } #endif src = Strdup(optionpanel_str); Strcat_charp(src, "<table><tr><td>"); for (i = 0; sections[i].name != NULL; i++) { Strcat_m_charp(src, "<h1>", sections[i].name, "</h1>", NULL); p = sections[i].params; Strcat_charp(src, "<table width=100% cellpadding=0>"); while (p->name) { Strcat_m_charp(src, "<tr><td>", p->comment, NULL); Strcat(src, Sprintf("</td><td width=%d>", (int)(28 * pixel_per_char))); switch (p->inputtype) { case PI_TEXT: Strcat_m_charp(src, "<input type=text name=", p->name, " value=\"", html_quote(to_str(p)->ptr), "\">", NULL); break; case PI_ONOFF: x = atoi(to_str(p)->ptr); Strcat_m_charp(src, "<input type=radio name=", p->name, " value=1", (x ? " checked" : ""), ">YES <input type=radio name=", p->name, " value=0", (x ? "" : " checked"), ">NO", NULL); break; case PI_SEL_C: tmp = to_str(p); Strcat_m_charp(src, "<select name=", p->name, ">", NULL); for (s = (struct sel_c *)p->select; s->text != NULL; s++) { Strcat_charp(src, "<option value="); Strcat(src, Sprintf("%s\n", s->cvalue)); if ((p->type != P_CHAR && s->value == atoi(tmp->ptr)) || (p->type == P_CHAR && (char)s->value == *(tmp->ptr))) Strcat_charp(src, " selected"); Strcat_char(src, '>'); Strcat_charp(src, s->text); } Strcat_charp(src, "</select>"); break; #ifdef USE_M17N case PI_CODE: tmp = to_str(p); Strcat_m_charp(src, "<select name=", p->name, ">", NULL); for (c = *(wc_ces_list **) p->select; c->desc != NULL; c++) { Strcat_charp(src, "<option value="); Strcat(src, Sprintf("%s\n", c->name)); if (c->id == atoi(tmp->ptr)) Strcat_charp(src, " selected"); Strcat_char(src, '>'); Strcat_charp(src, c->desc); } Strcat_charp(src, "</select>"); break; #endif } Strcat_charp(src, "</td></tr>\n"); p++; } Strcat_charp(src, "<tr><td></td><td><p><input type=submit value=\"OK\"></td></tr>"); Strcat_charp(src, "</table><hr width=50%>"); } Strcat_charp(src, "</table></form></body></html>"); buf = loadHTMLString(src); #ifdef USE_M17N if (buf) buf->document_charset = OptionCharset; #endif return buf; }
static int ftp_login(FTP ftp) { int sock, status; sock = openSocket(ftp->host, "ftp", 21); if (sock < 0) goto open_err; if (ftppass_hostnamegen && !strcmp(ftp->user, "anonymous")) { size_t n = strlen(ftp->pass); if (n > 0 && ftp->pass[n - 1] == '@') { #ifdef INET6 struct sockaddr_storage sockname; #else struct sockaddr_in sockname; #endif socklen_t socknamelen = sizeof(sockname); if (!getsockname(sock, (struct sockaddr *)&sockname, &socknamelen)) { struct hostent *sockent; Str tmp = Strnew_charp(ftp->pass); #ifdef INET6 char hostbuf[NI_MAXHOST]; if (getnameinfo((struct sockaddr *)&sockname, socknamelen, hostbuf, sizeof hostbuf, NULL, 0, NI_NAMEREQD) == 0) Strcat_charp(tmp, hostbuf); else if (getnameinfo((struct sockaddr *)&sockname, socknamelen, hostbuf, sizeof hostbuf, NULL, 0, NI_NUMERICHOST) == 0) Strcat_m_charp(tmp, "[", hostbuf, "]", NULL); else Strcat_charp(tmp, "unknown"); #else if ((sockent = gethostbyaddr((char *)&sockname.sin_addr, sizeof(sockname.sin_addr), sockname.sin_family))) Strcat_charp(tmp, sockent->h_name); else Strcat_m_charp(tmp, "[", inet_ntoa(sockname.sin_addr), "]", NULL); #endif ftp->pass = tmp->ptr; } } } ftp->rf = newInputStream(sock); ftp->wf = fdopen(dup(sock), "wb"); if (!ftp->rf || !ftp->wf) goto open_err; IStype(ftp->rf) |= IST_UNCLOSE; ftp_command(ftp, NULL, NULL, &status); if (status != 220) goto open_err; if (fmInitialized) { message(Sprintf("Sending FTP username (%s) to remote server.", ftp->user)->ptr, 0, 0); refresh(); } ftp_command(ftp, "USER", ftp->user, &status); /* * Some ftp daemons(e.g. publicfile) return code 230 for user command. */ if (status == 230) goto succeed; if (status != 331) goto open_err; if (fmInitialized) { message("Sending FTP password to remote server.", 0, 0); refresh(); } ftp_command(ftp, "PASS", ftp->pass, &status); if (status != 230) goto open_err; succeed: return TRUE; open_err: ftp_close(ftp); return FALSE; }
Buffer * link_list_panel(Buffer *buf) { LinkList *l; AnchorList *al; Anchor *a; FormItemList *fi; int i; char *t, *u, *p; ParsedURL pu; /* FIXME: gettextize? */ Str tmp = Strnew_charp("<title>Link List</title>\ <h1 align=center>Link List</h1>\n"); if (buf->bufferprop & BP_INTERNAL || (buf->linklist == NULL && buf->href == NULL && buf->img == NULL)) { return NULL; } if (buf->linklist) { Strcat_charp(tmp, "<hr><h2>Links</h2>\n<ol>\n"); for (l = buf->linklist; l; l = l->next) { if (l->url) { parseURL2(l->url, &pu, baseURL(buf)); p = parsedURL2Str(&pu)->ptr; u = html_quote(p); if (DecodeURL) p = html_quote(url_decode2(p, buf)); else p = u; } else u = p = ""; if (l->type == LINK_TYPE_REL) t = " [Rel]"; else if (l->type == LINK_TYPE_REV) t = " [Rev]"; else t = ""; t = Sprintf("%s%s\n", l->title ? l->title : "", t)->ptr; t = html_quote(t); Strcat_m_charp(tmp, "<li><a href=\"", u, "\">", t, "</a><br>", p, "\n", NULL); } Strcat_charp(tmp, "</ol>\n"); } if (buf->href) { Strcat_charp(tmp, "<hr><h2>Anchors</h2>\n<ol>\n"); al = buf->href; for (i = 0; i < al->nanchor; i++) { a = &al->anchors[i]; if (a->hseq < 0 || a->slave) continue; parseURL2(a->url, &pu, baseURL(buf)); p = parsedURL2Str(&pu)->ptr; u = html_quote(p); if (DecodeURL) p = html_quote(url_decode2(p, buf)); else p = u; t = getAnchorText(buf, al, a); t = t ? html_quote(t) : ""; Strcat_m_charp(tmp, "<li><a href=\"", u, "\">", t, "</a><br>", p, "\n", NULL); } Strcat_charp(tmp, "</ol>\n"); } if (buf->img) { Strcat_charp(tmp, "<hr><h2>Images</h2>\n<ol>\n"); al = buf->img; for (i = 0; i < al->nanchor; i++) { a = &al->anchors[i]; if (a->slave) continue; parseURL2(a->url, &pu, baseURL(buf)); p = parsedURL2Str(&pu)->ptr; u = html_quote(p); if (DecodeURL) p = html_quote(url_decode2(p, buf)); else p = u; if (a->title && *a->title) t = html_quote(a->title); else t = html_quote(url_decode2(a->url, buf)); Strcat_m_charp(tmp, "<li><a href=\"", u, "\">", t, "</a><br>", p, "\n", NULL); a = retrieveAnchor(buf->formitem, a->start.line, a->start.pos); if (!a) continue; fi = (FormItemList *)a->url; fi = fi->parent->item; if (fi->parent->method == FORM_METHOD_INTERNAL && !Strcmp_charp(fi->parent->action, "map") && fi->value) { MapList *ml = searchMapList(buf, fi->value->ptr); ListItem *mi; MapArea *m; if (!ml) continue; Strcat_charp(tmp, "<br>\n<b>Image map</b>\n<ol>\n"); for (mi = ml->area->first; mi != NULL; mi = mi->next) { m = (MapArea *) mi->ptr; if (!m) continue; parseURL2(m->url, &pu, baseURL(buf)); p = parsedURL2Str(&pu)->ptr; u = html_quote(p); if (DecodeURL) p = html_quote(url_decode2(p, buf)); else p = u; if (m->alt && *m->alt) t = html_quote(m->alt); else t = html_quote(url_decode2(m->url, buf)); Strcat_m_charp(tmp, "<li><a href=\"", u, "\">", t, "</a><br>", p, "\n", NULL); } Strcat_charp(tmp, "</ol>\n"); } } Strcat_charp(tmp, "</ol>\n"); } return loadHTMLString(tmp); }